UIWebView将垂直滚动事件委托给父级,如果滚动到顶部或底部

时间:2012-05-31 12:10:19

标签: ios uiwebview uiscrollview

我在UIScrollView中有一个UIWebView,它是分页的。基本上我想用滚动/拖动手势在不同的webview之间切换。水平它工作正常。如果webview滚动到“页面边框”,则滚动/平移事件将传递到滚动视图,以便显示下一页。在垂直轴上,这不起作用。似乎没有传递给scrollview的事件。这可能是弹跳的问题,我禁用了,因为我想,它会消耗这个事件。但即使禁用弹跳,这也行不通。

我之前在一个scrollview中使用TextViews进行了测试,这也很有效。可能是webviews的一种特殊行为。

任何想法,我是如何让这个工作的?我是否必须实现事件侦听器并手动将事件传递给scrollview?

此外,如果您对如何实现此类布局有更好的了解,请告诉我们。正如我所说,我希望有一个不同视图的网格,可以通过fling / scroll手势来改变。与AppStore应用程序类似,应用程序的详细信息可以垂直滚动,屏幕截图可以水平滚动。

干杯 亨利克

3 个答案:

答案 0 :(得分:9)

所以,我明白了。

首先我设置webview的委托,以便我获得滚动事件,并且可以检查webview是否滚动到顶部或底部:

- (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);
    }
}

然后我在webview的scrollview上注册了额外的滑动手势识别器:

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];

请注意对[self.webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeUp];的来电。这些是绝对必要的,因为没有它们,webview的平移手势识别器总是在它们到达轻扫手势识别器之前消耗事件。这些电话改变了优先事项。

在swipeUp和swipeDown方法中,我计算下一个“页面”的位置,并将父滚动视图滚动到此位置(如果实际存在下一页)。

最后一件事是检查,如果webview滚动到顶部或底部,并且只接受这种情况下的手势。因此,您必须实现手势识别器的委托:

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

    return false;
}

你可能还必须禁用滚动弹跳才能使这个工作与网页一起使用,网页很小,根本不滚动:webView.scrollView.bounces = false;

答案 1 :(得分:4)

滚动视图真的是垂直滚动还是webview? 我自己也没试过,但也许这会有所帮助......

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

或......

webView.userInteractionEnabled = NO;

答案 2 :(得分:2)

我以前做过这个,但我结束了使用Javascript和Obj-c。我添加了一个函数,检查(使用JQuery)页面是在滚动的底部还是顶部(我需要为我的应用程序)。然后我使用NSTimer调用该函数:

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

我知道它有点丑陋,但这是我当时发现这种方式的唯一方法,它就是这样做的。这是我使用的代码:

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