UIWebView delegate vertical scroll event for parent when scrolling up or down

I have a UIWebView in a UIScrollView that is paginated. Mostly I want to switch between different webviews using scroll / throw gestures. Horizontally works fine. If the web view scrolls to the "page border", the scroll / pan event is passed to the scroll, so the next page is displayed. On the vertical axis, this does not work. It seems that the scrollview event is not being dispatched. It could be a bounce problem that I disabled, because, in my opinion, it will consume the event. But even with the shutdown turned off, this does not work.

I tested this before using TextViews in scrollview, which worked too. There may be special webview behavior.

Any idea how I can make this work? Should I implement event listeners and pass events manually in scrollview?

Also, if you have an idea how to implement such a layout, let me know. As I said, I want to have a grid of different views that can be changed using fling / scroll gestures. Similar to the AppStore application, where application details can be scrolled vertically, and screenshots can be scrolled horizontally.

Cheers Henrik

+4
source share
3 answers

So, I figured it out.

First, I set the web view delegate to get scroll events and check if the web view scrolls up or down:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if([scrollView isEqual:webView.scrollView]) { float contentHeight = scrollView.contentSize.height; float height = scrollView.frame.size.height; float offset = scrollView.contentOffset.y; if(offset == 0) { webViewScrolledToTop = true; webViewScrolledToBottom = false; } else if(height + offset == contentHeight) { webViewScrolledToTop = false; webViewScrolledToBottom = true; } else { webViewScrolledToTop = false; webViewScrolledToBottom = false; } //NSLog(@"Webview is at top: %i or at bottom: %i", webViewScrolledToTop, webViewScrolledToBottom); } } 

Then I registered additional gesture recognizers when viewing the webview scroll:

 swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeUp)]; swipeUp.direction = UISwipeGestureRecognizerDirectionUp; swipeUp.delegate = self; [self.webView.scrollView addGestureRecognizer:swipeUp]; [self.webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeUp]; swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDown)]; swipeDown.direction = UISwipeGestureRecognizerDirectionDown; swipeDown.delegate = self; [self.webView.scrollView addGestureRecognizer:swipeDown]; [self.webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeDown]; 

Note the calls to [self.webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeUp]; . This is absolutely necessary, because without them, a web-based gesture recognizer will always consume events before they reach the gesture recognizer. These challenges change priorities.

In the swipeUp and swipeDown methods, I calculate the position of the next “page” and scroll the parent scroll view to that position if there really is a next page.

The last thing to check is if the webview scrolls up or down and only accepts gestures in this case. To do this, you need to implement the gesture recognizer delegate:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if(gestureRecognizer == swipeUp) { return webViewScrolledToBottom; } else if(gestureRecognizer == swipeDown) { return webViewScrolledToTop; } return false; } 

You may also need to disable scroll scans so that this work with such small web pages that they do not scroll at all: webView.scrollView.bounces = false;

+9
source

Is it a scrollview that scrolls vertically or is it a webview? I have not tried it myself, but maybe this will help ...

 webView.scrollView.scrollEnabled = NO; webView.scrollView.bounces = NO; 

or...

 webView.userInteractionEnabled = NO; 
+4
source

I have done this before, but I ended up using Javascript and Obj-c. I added a function that checks (using jQuery) if the page is at the bottom or at the top of the scroll (I need this for my application). Then I call this function with NSTimer using:

 NSString *str= [webView stringByEvaluatingJavaScriptFromString:@"JSFunction()"]; 

I know how ugly it is, but that was the only way I found at this time, and it just does the job. Here is the code I used:

 function JSFunction() { var docHeight = $(document).height(); var scroll = $(window).height() + $(window).scrollTop(); if (docHeight == scroll || $(window).scrollTop() < 10) return "TOP"; else return "BODY"; } 
+2
source

Source: https://habr.com/ru/post/1415352/


All Articles