WKWebView zooming not working properly

3.4k views Asked by At

I am using XWalkView which is a subclass of WKWebView, added as a subview to a container view programmatically. I am trying to zoom the content page of the WKWebView but it does not zoom first time. The WKWebView zooms the content page subsequently, i.e. when I pinch zoom or do double tap zoom it zooms WKWebView itself or container view (my guess) & after that, doing zoom gestures again the content page is zoomed (which is expected behaviour).

The question is that how to make the content page of WKWebView zoom whenever the zoom gesture is performed.

I am conforming to UIScrollViewDelegate protocol in my ViewController.h as below:

@interface ViewController : UIViewController<UIScrollViewDelegate, WKNavigationDelegate, WKUIDelegate>

I am setting the delegate to self in viewDidLoad as below:

xWalkView.scrollView.delegate = self;

Setting zooming scales in viewDidLoad as below:

xWalkView.scrollView.minimumZoomScale = 1;
xWalkView.scrollView.maximumZoomScale = 6;

& implementing the protocol methods in ViewController.m as below:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    if (shouldPageNotZoom) {
        NSLog(@"viewForZoomingInScrollView YES");
        return nil;
    } else {
        NSLog(@"viewForZoomingInScrollView NO");
        return xWalkView.scrollView.subviews[0];
    }
}

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {

}

I am using a BOOL shouldPageNotZoom & setting it YES or NO based on URL depending on whether zooming is required or not. On pages where zooming is required I can see the log of else block (NSLog(@"viewForZoomingInScrollView NO");) being printed in log area & on pages where zooming is not required I can see the log of if block (NSLog(@"viewForZoomingInScrollView YES");). Which is working. The only problem is content page does not zoom on first zooming gesture instead WKWebView or container view is zoomed (I guess), but zooms on subsequent zoom gestures.

After some observation I found that subview at index 0 of scrollview is being zoomed the first & subsequent times (but the content page zooms subsequent times not the first time), which is being returned in viewForZoomingInScrollView. Which should be the case, & is. I did this by assigning the tag values to each view & seeing the tag value by logging the tag value in scrollViewDidEndZooming method in log area as below:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    if (shouldPageNotZoom) {
        NSLog(@"viewForZoomingInScrollView YES");
        return nil;
    } else {
        NSLog(@"viewForZoomingInScrollView NO");
        xWalkView.scrollView.tag = 20;
        xWalkView.tag = 15;
        xWalkView.scrollView.subviews[0].tag = 10;
        _containerView.tag = 5;
        return xWalkView.scrollView.subviews[0];
    }
}

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    NSLog(@"tag %li", (long) view.tag);
}

Giving the below log:

2017-11-28 17:21:36.610753+0530 MyApp[4614:241659] tag 10 //Getting this 1st time of zooming
2017-11-28 17:21:59.369461+0530 MyApp[4614:241659] tag 10 //Getting this at subsequent zooms 

I don't know what am I missing.

Please comment if any clarification is needed.

1

There are 1 answers

0
Osama Mohammed Shaikh On BEST ANSWER

Got the solution! Returning the last subview first time & first subview of scrollview on subsequent zooms in viewForZoomingInScrollView method solved the problem, as shown below:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    if (shouldPageNotZoom) {
        NSLog(@"viewForZoomingInScrollView YES");
        return nil;
    } else {
        NSLog(@"viewForZoomingInScrollView NO");
        xWalkView.scrollView.tag = 20;
        xWalkView.tag = 15;
        xWalkView.scrollView.subviews[0].tag = 10;
        _containerView.tag = 5;

        if (isFirstTimeZooming) {
            return xWalkView.scrollView.subviews[xWalkView.scrollView.subviews.count - 1];
        } else {
            return xWalkView.scrollView.subviews[0];
        }
    }
}

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    NSLog(@"tag %li", (long) view.tag);
    isFirstTimeZooming = NO;
}

isFirstTimeZooming is set to YES on load of the page in didStartProvisionalNavigation method & set to NO in scrollViewDidEndZooming method so that first subview of scrollview can be passed on subsequent zooming.

I had to use isFirstTimeZooming because if I pass last subview only in viewForZoomingInScrollView the zooming problem was reversed, i.e. it was zooming properly first time but not on subsequent zooms.