Программное масштабирование UIWebView без жестов - центральная точка рассчитывается неправильно

Проблема

У меня есть UIWebView внутри моего приложения для iPad, которое мне нужно масштабировать программно, но без использования жестов / касаний. Приложение. имеет кнопки «+» и «-» для увеличения и уменьшения масштаба с шагом, определяемым пользователем (это приложение для слабовидящих).

Эта функция +/- кнопки масштабирования раньше работала на 100% нормально, когда мое приложение. использовал UIImageView внутри UIScrollView (вместо WebView). ImageView был фактическим видом, который был увеличен, а CenterPoint был рассчитан для метода ZoomToRect ScrollView.

Теперь у меня есть WebView, который, как я знаю, содержит ScrollView в качестве подпредставления. Я попытался адаптировать код, который ранее работал с комбинацией ImageView / ScrollView, чтобы вместо этого увеличивать ScrollView WebView, но он больше не вычисляет CenterPoint правильно для zoomToRect:.

Что происходит:

WebView масштабирует правильно с точки зрения уровня масштабирования, но центральная точка всегда неверна. По какой-то причине экран всегда увеличивается в левом верхнем углу.

Еще одна странная проблема заключается в том, что после самого первого увеличения масштаба вы не можете прокручивать WebView за пределами видимой части экрана. Если вы попытаетесь это сделать, он покажет часть содержимого за пределами текущей видимой области, но мгновенно откроется.

Что я пробовал:

Я пытаюсь увеличить масштаб ScrollView UIWebView.

Я создаю указатель на ScrollView и устанавливаю «себя» в качестве его делегата. Затем я устанавливаю различные переменные, такие как scrSize (размер представления для увеличения) и ZoomHandler (поясняется ниже):

- (void)viewDidLoad {
  // ... Various UIWebView setup ...    
  [self LoadURL];

  // Zooming & scrollview setup
  zoomHandler = [[ZoomHandler alloc] initWithZoomLevel: ZOOM_STEP];
  scrSize = CGPointMake(self.WebView.frame.size.width, self.WebView.frame.size.height);

  scrollView = [WebView.subviews objectAtIndex:0];
  [scrollView setTag:ZOOM_VIEW_TAG];
  [scrollView setMinimumZoomScale:MINIMUM_SCALE];
  [scrollView setZoomScale:1];
  [scrollView setMaximumZoomScale:10];
  scrollView.bounces = FALSE;
  scrollView.bouncesZoom = FALSE;
  scrollView.clipsToBounds = NO;
  [scrollView setDelegate:self];

  [super viewDidLoad];
}

Чтобы переопределить ограничения масштабирования WebView по умолчанию, я вставляю этот Javascript в загруженную веб-страницу в методе webViewDidFinishLoad:

function increaseMaxZoomFactor() {
  var element = document.createElement('meta');
  element.name = "viewport";
  element.content = "maximum-scale=10 minimum-scale=1 initial-scale=1 user-scalable=yes width=device-width height=device-height;"
  var head = document.getElementsByTagName('head')[0];
  head.appendChild(element);
}

Код CenterPoint:

Этот код используется для вычисления CenterPoint для передачи в zoomToRect :. Это сработало на 100% нормально, когда я масштабировал ImageView внутри ScrollView.

-(IBAction)zoomOut {
    float newScale = [scrollView zoomScale] / ZOOM_STEP;
    if( [scrollView zoomScale] > MINIMUM_SCALE) {
        [self handleZoomWith:newScale andZoomType: FALSE];
    }
}

-(IBAction)zoomIn {
    float newScale = [scrollView zoomScale] * ZOOM_STEP;
    if( [scrollView zoomScale] < MAXIMUM_SCALE){
        [self handleZoomWith:newScale andZoomType: TRUE];
    }
}

-(void)handleZoomWith: (float) newScale andZoomType:(BOOL) isZoomIn {
    CGPoint newOrigin = [zoomHandler getNewOriginFromViewLocation: [scrollView contentOffset] 
                                                        viewSize: scrSize andZoomType: isZoomIn];
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:newOrigin];
    [scrollView zoomToRect:zoomRect animated:YES];
}

- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
    CGRect zoomRect;

    //  At a zoom scale of 1.0, it would be the size of the scrollView's bounds.
    //  As the zoom scale decreases, so more content is visible, the size of the rect grows.
    zoomRect.size.height = [WebView frame].size.height / scale;
    zoomRect.size.width  = [WebView frame].size.width  / scale;

    // Choose an origin so as to get the right center.
    zoomRect.origin.x = center.x / scale;
    zoomRect.origin.y = center.y / scale;

    return zoomRect;
}

/**
 Determine the origin [THIS IS INSIDE ZOOMHANDLER]
 */
-(CGPoint) getNewOriginFromViewLocation: (CGPoint) oldOrigin viewSize: (CGPoint) viewSize andZoomType:(BOOL) isZoomIn {

    // Calculate original center (add the half of the width/height of the screen)
    float oldCenterX = oldOrigin.x + (viewSize.x / 2);
    float oldCenterY = oldOrigin.y + (viewSize.y / 2);

    // Xalculate the new center
    CGPoint newCenter;
    if(isZoomIn) {
        newCenter = CGPointMake(oldCenterX * zoomLevel, oldCenterY * zoomLevel);
    } else {
        newCenter = CGPointMake(oldCenterX / zoomLevel, oldCenterY / zoomLevel);
    }

    // Calculate the new origin (deduct the half of the width/height of the screen)
    float newOriginX = newCenter.x - (viewSize.x / 2);
    float newOriginY = newCenter.y - (viewSize.y / 2);

    return CGPointMake(newOriginX, newOriginY);
}

Кто-нибудь знает, почему CenterPoint не рассчитывается правильно? Любая помощь будет очень признательна; Я застрял на этом уже неделю.

Спасибо алекс


person AlexFZ    schedule 27.06.2011    source источник


Ответы (1)


Вы пробовали реализовать масштабирование с помощью JavaScript, а не прокрутки UIWebView?

Я считаю, что вы можете увеличить веб-просмотр, позвонив:

[webView stringByEvaluatingJavaScriptFromString:@"document.body.style.zoom = 5.0;"]; (используйте ZOOM_STEP в качестве значения)

Вы также можете рассчитать центр окна браузера с помощью JS:

posY = getScreenCenterY();
posX = getScreenCenterX();

function getScreenCenterY() {
    var y = 0;
    y = getScrollOffset()+(getInnerHeight()/2);
    return(y);
}

function getScreenCenterX() {
    return(document.body.clientWidth/2);
}

function getInnerHeight() {
    var y;
    if (self.innerHeight) // all except Explorer
    {
        y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight)
    // Explorer 6 Strict Mode
    {
        y = document.documentElement.clientHeight;
    }
    else if (document.body) // other Explorers
    {
        y = document.body.clientHeight;
    }
    return(y);
}

function getScrollOffset() {
    var y;
    if (self.pageYOffset) // all except Explorer
    {
        y = self.pageYOffset;
    }
    else if (document.documentElement &&
document.documentElement.scrollTop) // Explorer 6 Strict
    {
        y = document.documentElement.scrollTop;
    }
    else if (document.body) // all other Explorers
    {
        y = document.body.scrollTop;
    }
    return(y);
}

(источник: http://sliceofcake.wordpress.com/2007/09/13/use-javascript-to-find-the-center-of-the-browser/)

person Mutix    schedule 05.12.2011
comment
Я только что увидел твой ответ! Потребность в решении уже давно ушла, но знание того, как это могло быть решено, определенно по-прежнему полезно. Спасибо! - person AlexFZ; 13.12.2011