ScrollOffset in UIWebView?

I’m having a really hard time understanding delegates and object inheritance (if I may use this word) and I think I need a simple (or so I think) thing: catch scrollViewDidScroll event in UIWebView and get offset (basically, just to know if scroll is not on top/bottom, so I could hide navigation and tab bars).

Is there any way I could do it? I already using UIWebviewDelegate in my view controller to “shouldStartLoadWithRequest”. Maybe I could some how use UIScrollViewDelegate too for scrollViewDidScroll? If yes, then how?

  • repeat local notification
  • Difference between Strong and Weak IBOutlets
  • Exception in iPad, UIImagePickerController must be presented via UIPopoverController
  • Swift can't show back button after hiding it
  • Background image not loading on device
  • How to use multiple iOS custom view controllers without a navigation controller
  • I really have trouble understanding delegates. I’ve red some articles, but still, in practice, I can’t manage to use them.

    Any help or info would be lovely.

    Thank you in advance!

    7 Solutions Collect From Internet About “ScrollOffset in UIWebView?”

    There is a scrolling view in the UIWebView, but it a) isn’t a UIScrollView, and b) is something Apple considers a private implementation detail (and you should too). I only really have two suggestions:

    1. File a bug with Apple asking them to expose more of the infrastructure of the web view, or at least add some more delegate methods by which we can be notified of these sorts of events.
    2. Add some JavaScript code to your page that listens from scroll events, and notifies your app of them.

    The basic foundation of #2 is to load a fake URL, and have your web view delegate process (and abort!) that load. (This question has come up a few times here on Stack Overflow.)

    UPDATE:

    As of iOS 5, there is now a public scrollView property on UIWebView that you can use to customize scrolling behavior. The exact view hierarchy of the web view remains an undocumented implementation detail, but this gives you a sanctioned way to access this piece of it.

    To retrieve scroll events on UIWebView I personnaly use this code to get the scrollview that is inside the UIWebView :

    - (void) addScrollViewListener
    {
        UIScrollView* currentScrollView;
        for (UIView* subView in self.myWebView.subviews) {
            if ([subView isKindOfClass:[UIScrollView class]]) {
                currentScrollView = (UIScrollView*)subView;
                currentScrollView.delegate = self;
            }
        }
    }
    

    It’s working. You can also use it to call [currentScrollView setContentOffset:offSet animated:YES]; The only problem may be not to pass Apple code checking. I don’t know yet since I’m still in coding phase.

    [UPDATE] The app with this code is in the app store for 4 months now and used by 40 000 users. I didn’t have any trouble [UPDATE]

    You can use the following methods to solve your problem.

    For getting the pageOffset:

    int pageYOffset = [[webViewObj stringByEvaluatingJavaScriptFromString:@”window.pageYOffset”] intValue];

    For getting the total scroll height of a webpage:

    int scrollHeight = [[webViewObj stringByEvaluatingJavaScriptFromString:@”document.documentElement.scrollHeight”] intValue];

    For scrolling the webpage to a particular offset:

    [webViewObj stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@”document.body.scrollTop = %d”,scrollHeight ]];

    I made a modification to detect the class with isKindOfClass. Works – but may have issues with Apple code checking as stated above.

    UIScrollView* currentScrollView;
    for (UIView* subView in terms.subviews) {
        if ([subView isKindOfClass:[UIScrollView class]]) {
            NSLog(@"found scroll view");
            currentScrollView = (UIScrollView *)subView;
            currentScrollView.delegate = self;
        }
    }
    

    Old thread, I know –

    As of iOS 5.0 you can use

    myAccountWebView.scrollview
    

    to access content size and offset.

    It’s a good question. UIWebView is not a subclass of UIScrollView, although I can see why one might think it is. That means using the UIScrollViewDelegate methods is not an option to do what you want, and the UIWebViewDelegate protocol does not respond to those scrolling event type of messages. I don’t think there’s an easy way to detect scrolling events in a web view.

    I tired the delegate method and found it prevented the view from scrolling when the keyboard was shown. I found that by adding an observer you do not override the current delegate and will prevent you from effecting the webview performance.

    for (UIView* subView in myAccountWebView.subviews) {
        if ([subView isKindOfClass:[UIScrollView class]]) 
        {
            NSLog(@"found scroll view");
            [((UIScrollView*)subView) addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
        }
    }