iOS中UIScrollView内部的UIWebView

17
我想在UIScrollView中放置一个UIWebView。由于UIWebView有时会超出iPhone屏幕的边界,所以我需要一种滚动视图的方法来查看所有内容(但我不想使用UIWebView内置的滚动)。因此,我考虑将所有内容放在UIScrollView中,然后使UIScrollView的高度等于UIWebView和其中其他视图的高度。
这里是一张图片,以帮助描述我的问题:

Interface Builder Image

1个回答

39
我完全做了同样的事情。以下是我如何使其工作的方法:
  1. 将UIWebView添加为UIScrollView的子视图(显然)。
  2. 禁用UIWebView的原生滚动(可以通过迭代UIWebView的子视图来完成,直到找到它的UIScrollView,并在其中设置scrollEnabled = NO)。
  3. 将UIScrollView和UIWebView的frame的contentSize设置为UIWebView HTML内容的大小。

最后一点有些棘手,因为你无法确定HTML是否在UIWebViewDelegate中的webViewDidFinishLoad:被完全渲染。

以下是一个可靠的获取HTML内容大小的方法:

1.在HTML中添加一个javascript函数,在HTML文档准备就绪时调用:

window.onload = function() {
    window.location.href = "ready://" + document.body.offsetHeight;
}

这个函数会发送一个带有内容高度参数的请求。

2. 在你的UIWebViewDelegate中,你可以拦截这个请求:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
        NSURL *url = [request URL];
        if (navigationType == UIWebViewNavigationTypeOther) {
           if ([[url scheme] isEqualToString:@"ready"]) {
               float contentHeight = [[url host] floatValue];
               yourScrollView.contentSize = CGSizeMake(yourScrollView.frame.size.width, contentHeight + yourWebView.frame.origin.y);
               CGRect fr = yourWebView.frame;
               fr.size = CGSizeMake(yourWebView.frame.size.width, contentHeight);
               yourWebView.frame = fr;

               return NO;       
        }

        return YES;
}

希望能帮到您。

更新:

这是 Swift 2 版本:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    guard navigationType == .Other else { return true }
    if let url = request.URL, let host = url.host {
        guard url.scheme == "ready" else { return true }
        if let contentHeight = Float(host) {
            yourScrollView.contentSize = CGSizeMake(yourScrollView.bounds.size.width, CGFloat(contentHeight))
            var fr = webView.frame
            fr.size = CGSizeMake(fr.size.width, CGFloat(contentHeight))
            webView.frame = fr
        }

        return false
    }

    return true
}

有人可以将它翻译成Swift吗? - Yestay Muratov
@YestayMuratov 抱歉回复晚了。我已经在我的回答中添加了Swift 2版本。 - joern
@joern 如果HTML内容中有类似于“显示更多”链接并附有JS(用于展开或加载和展开文章),那么这种方法将无法奏效,对吗? - OgreSwamp
1
@OgreSwamp 没错。它无法处理用户交互后更改其高度的HTML内容。这篇博客文章描述了如何处理“显示更多”场景的方法:http://www.pixeldock.com/blog/set-a-uiwebviews-height-to-the-height-of-its-html-content-using-auto-layout/ 该示例使用自动布局,但您也可以在不使用自动布局的情况下使用KVO部分。简而言之,您观察UIWebView内部的UIScrollViewcontentSize,并在contentView的高度更改时更改UIWebView的高度。 - joern

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接