iOS:检测到达顶部或底部的UIWebView

时间:2012-03-02 14:55:19

标签: iphone ios uiwebview

如何检测到达顶部或底部的UIWebView? 因为当我到达底部时我需要触发一个动作。

那可行吗?

6 个答案:

答案 0 :(得分:24)

首先,您不应将UIWebView置于UIScrollView文档中提到的UIWebView内。

  

重要提示:您不应在UIScrollView对象中嵌入UIWebView或UITableView对象。如果这样做,可能会导致意外行为,因为两个对象的触摸事件可能会混淆和错误处理。

相反,您可以通过UIScrollView属性访问UIWebView。您的视图控制器可以实现UIScrollViewDelegate

@interface MyViewController : UIViewController<UIScrollViewDelegate>
@end

然后你可以挂钩到UIScrollView:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Set self as scroll view protocol
    webView.scrollView.delegate = self;
}

然后最终检测到达到的顶部和底部:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{   
    if(scrollView.contentOffset.y 
       >= 
       (scrollView.contentSize.height - scrollView.frame.size.height)){
        NSLog(@"BOTTOM REACHED");
    }
    if(scrollView.contentOffset.y <= 0.0){
        NSLog(@"TOP REACHED");
    }
}

Voila,您可以检测到达到顶部和底部的时间。

答案 1 :(得分:2)

如果您的目标是iOS 5,UIWebView有一个只读scrollView属性,可让您访问基础UIScrollView

从那里,您可以挂钩scrollView的scrollViewDidScroll:委托方法以接收有关滚动事件的信息。

答案 2 :(得分:2)

你可以试一试 -

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if(scrollView == yourWebView)
    {
        int percentScrolled = abs((int)ceil((scrollView.contentOffset.y/scrollView.contentSize.height)*100));
        if(percentScrolled > 100 || percentScrolled < 0)
            percentScrolled = 0;

        if(percentScrolled > 90)
        {
            //scroll percent is 90. do your thing here.
        }
    }
    return;
}

这里做的是每次用户滚动webView,计算%滚动和&amp;当%滚动即将结束时(比如说> 90%),做任何你打算做的事情。

答案 3 :(得分:1)

您可以将UIWebView放在UIScrollView中(已禁用弹跳,因此视图的弹跳行为不会以任何方式发生冲突)然后当UIWebView滚动到底部时,上面的UIScrollView将接管滚动并且您可以听其滚动事件。

抓一点。

似乎毕竟不是那么简单。

您可以在UIWebView的子视图中找到UIScrollView,并点击其滚动委托方法。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@"We scrolled! Offset now is %f, %f", scrollView.contentOffset.x, scrollView.contentOffset.y);
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIWebView *view = (UIWebView *)self.view;

    for (UIView * subview in view.subviews) {
        if ([subview isKindOfClass:[UIScrollView class]]) {
            UIScrollView *webScrollView = (UIScrollView *)subview;
            webScrollView.delegate = self;
            break;
        }
    }

    [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://stackoverflow.com"]]];
}

当UIWebView加载Web内容时,其UIScrollView应更改其contentSize属性。您可以使用它来确定您是否已经在底部或顶部。

答案 4 :(得分:0)

您可以使用KVO检测contentOffset实例的UIWebView属性中的任何更改。

警告:请注意,因为滚动时此属性经常变化,下面示例中的事件会频繁弹出。在每次contentOffset更改时都不要实现或调用高成本函数!

以下是在包含UIView的{​​{1}}子类中执行此操作的代码示例:

UIWebView

Apple在UIWebview文档中记录,您应该避免将UIWebview实例放在UIScrollView中以检测滚动的结束/开始。

答案 5 :(得分:0)

如果您使用的是Wkwebview:

我来晚了,我实现了wkwebview的委托来检查scrollview的顶部或底部。我曾经通过 evaluateJavaScript 函数读取javascript代码。在使用之前,请先设置Web视图的scrollview委托并实现UIScrollViewDelegate的 scrollViewDidEndDragging 委托功能

extension BaseWebViewController: UIScrollViewDelegate {
func scrollViewDidEndDragging(_ scrollView: UIScrollView,
                                   willDecelerate decelerate: Bool) {
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
    if complete != nil {
        self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
            let bodyScrollHeight = height as! CGFloat
            var bodyoffsetheight: CGFloat = 0
            var htmloffsetheight: CGFloat = 0
            var htmlclientheight: CGFloat = 0
            var htmlscrollheight: CGFloat = 0
            var wininnerheight: CGFloat = 0
            var winpageoffset: CGFloat = 0
            var winheight: CGFloat = 0

            //body.offsetHeight
            self.webView.evaluateJavaScript("document.body.offsetHeight", completionHandler: { (offsetHeight, error) in
                bodyoffsetheight = offsetHeight as! CGFloat

                self.webView.evaluateJavaScript("document.documentElement.offsetHeight", completionHandler: { (offsetHeight, error) in
                    htmloffsetheight = offsetHeight as! CGFloat

                    self.webView.evaluateJavaScript("document.documentElement.clientHeight", completionHandler: { (clientHeight, error) in
                        htmlclientheight = clientHeight as! CGFloat

                        self.webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (scrollHeight, error) in
                            htmlscrollheight = scrollHeight as! CGFloat

                            self.webView.evaluateJavaScript("window.innerHeight", completionHandler: { (winHeight, error) in
                                if error != nil {
                                    wininnerheight = -1
                                } else {
                                    wininnerheight = winHeight as! CGFloat
                                }

                                self.webView.evaluateJavaScript("window.pageYOffset", completionHandler: { (winpageOffset, error) in
                                    winpageoffset = winpageOffset as! CGFloat

                                    let docHeight = max(bodyScrollHeight, bodyoffsetheight, htmlclientheight, htmlscrollheight,htmloffsetheight)

                                    winheight = wininnerheight >= 0 ? wininnerheight : htmloffsetheight
                                    let winBottom = winheight + winpageoffset
                                    if (winBottom >= docHeight) {
                                        print("end scrolling")
                                    } else if winpageoffset == 0 {
                                            print("top of webview")
                                        }
                                })

                            })

                        })

                    })

                })
            })


        })
    }

})

}
}