adit
adit

Reputation: 33644

check if UIWebView scrolls to the bottom

How do I check/call a method when a user is at the bottom of the UIWebView when scrolling? I want to popup a view (add a subiview) when the user is at the bottom of the content.

Upvotes: 1

Views: 4063

Answers (5)

Sid
Sid

Reputation: 9536

This is how I would do it.

UIWebView conforms to UIScrollViewDelegate. Use the - (void)scrollViewDidScroll:(UIScrollView *)scrollView callback to keep track of when your UIWebView is scrolling:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
   //The webview is is scrolling
   int xPosition = [[webView stringByEvaluatingJavaScriptFromString: @"scrollX"] intValue];
   int yPosition = [[webView stringByEvaluatingJavaScriptFromString: @"scrollY"] intValue];
}

Now this method will be invoked whenever your webView scrolls. Your webView will have scrolled to the bottom when:

webView_content_height - webView(y) = webView.frame.height; //pseudo code

Your delegate callback will now look like:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
       //The webview is is scrolling
       int xPosition = [[webView stringByEvaluatingJavaScriptFromString: @"scrollX"] intValue];
       int yPosition = [[webView stringByEvaluatingJavaScriptFromString: @"scrollY"] intValue];

       if([webView stringByEvaluatingJavaScriptFromString: @"document.body.offsetHeight"] - yPosition == webView.frame.height)
       {
            //The user scrolled to the bottom of the webview
       }
    }

What the code translates to is that when the user scrolls to the bottom of the content, the difference between the webView's y Position (which is the y-coordinate of the webView's top left corner) and the bottom of the content will be equal to the height of the webview frame. The code acts upon this condition being satisfied to enter inside the if condition.

To be on the safe side, you could modify the if condition to have a margin for error (maybe + or - 10 pixels).

Upvotes: 0

sho
sho

Reputation: 769

Building on other ideas here, UIWebView conforms to the UIScrollViewDelegate protocol. You could subclass UIWebView and override the appropriate UIScrollViewDelegate methods, calling [super ...] so the original behavior is still present.

@interface SpecialWebview : UIWebView

@end

@implementation SpecialWebview

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [super scrollViewDidScroll:scrollView];

    // Check scroll position and handle events as needed...
}

@end

Upvotes: 1

jimmyg
jimmyg

Reputation: 580

Sorry, I was thinking UITableView. You are asking about a UIWebView. I don't know if this will work with the UIWebView.

I have code that does this using a UIScrollViewDelegate.

@interface myViewController : UIViewController_iPad <UIScrollViewDelegate> {
    UITableView *myTableView;
    ...
}

- (void)viewDidLoad {
    myTableView.delegate = self;
    ...
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // If necessary, verify this scrollview is your table:
    // if (scrollView == myTableView) {
        CGPoint offset = myTableView.contentOffset;
        if (myTableView.contentSize.height - offset.y >= myTableView.bounds.size.height)
        {
            // The table scrolled to the bottom. Do your stuff...
        }
    // }
}

Upvotes: 0

Nick Lockwood
Nick Lockwood

Reputation: 40995

Another option would be to inject some JavaScript into the web view and then use the window.onscroll event in JavaScript to detect when the user has scrolled to the bottom of the window (you can find plenty of examples online if detecting scroll events using JS).

Once you detect the the user is at the bottom, you could call back to the app by loading a fake url in the web view from the JavaScript by saying document.location.href = "http://madeupcallbackurl", then use the web view delegate to intercept that request and perform your native code logic.

Using the scrollview delegate is probably easier though if you can make that work!

Upvotes: 0

Oscar Gomez
Oscar Gomez

Reputation: 18488

First get the reference to the UIWebView scrollView using this property:

@property(nonatomic, readonly, retain) UIScrollView *scrollView

Once you get the reference to it you could check for the contentSize of it and compare it with the contentOffSet. You cannot make yourself a delegate of it, since the UIWebView is already the delegate for the scrollView, but that trick should work.

The problem is that you don't get the callBack when the scrolling is happening... so you would have to check every so often. Otherwise you will have to make yourself the delegate of the scrollView, and implement all the methods that UIWebView is implementing and mimic that behavior, and then check on the didScroll for that condition.

Upvotes: 0

Related Questions