【问题标题】:UIWebView in UIScrollView with autolayout带有自动布局的 UIScrollView 中的 UIWebView
【发布时间】:2015-10-23 00:39:57
【问题描述】:

我在使用此设置时遇到了很多问题。所以基本上我会显示一些高度可变的标签,然后是一个按钮,在视图的最后我需要一个 WebView 来显示一些 HTML 格式的文本。

我在加载内容时调整 web 视图高度约束,如下所示。

func webViewDidFinishLoad(webView: UIWebView) {
        nContentViewHeight.constant = webView.scrollView.contentSize.height
}

当第一次加载视图时,它可以完美运行。滚动效果很好,所有网页视图内容都可见。

但是当我旋转设备时,我不知道如何正确调整网络视图的大小。我尝试在

中再次加载内容
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation)

这样webViewDidFinishLoad 会再次触发并调整网络视图的大小。但这根本不起作用,因为 web 视图中滚动视图的 contentSize 没有改变。

不知道为什么我尝试了非常丑陋的解决方案,就是这样:

func fitWebAndScrollView(){
    let newRect = CGRectMake(nContentWebView.frame.minX, nContentWebView.frame.minY, self.view.frame.width, 10)
    let newWebView = UIWebView(frame: newRect)
    newWebView.delegate = self
    newWebView.tag = -12
    newWebView.scrollView.scrollEnabled = false
    self.view.addSubview(newWebView)
    newWebView.loadHTMLString(contentHtml, baseURL: nil)
}

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
    fitWebAndScrollView()
}

func webViewDidFinishLoad(webView: UIWebView) {
    nContentViewHeight.constant = webView.scrollView.contentSize.height
    if webView.tag == -12 {
        webView.removeFromSuperview()
        nContentViewHeight.constant *= 1.1 // longer the content is more of it is clipped
    }
}

这种方法可行,但在某些情况下,WebView 内容的底部会被剪裁,就好像内部滚动视图内容的大小计算不正确一样。

以前有人处理过这个吗?我一直认为这种事情不是一个额外的特殊用例。

感谢您的想法。

【问题讨论】:

    标签: ios swift uiscrollview uiwebview autolayout


    【解决方案1】:

    好吧,所以我设法通过这种方式解决了它

    func fitWebAndScrollView(){
        if let strH = nContentWebView.stringByEvaluatingJavaScriptFromString("document.getElementById(\"cnt\").offsetHeight;"),
        numH = NSNumberFormatter().numberFromString(strH){
            nContentViewHeight.constant = CGFloat(numH)+20
        }
    }
    
    override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
        fitWebAndScrollView()
    }
    
    func webViewDidFinishLoad(webView: UIWebView) {
        fitWebAndScrollView()
    }
    

    问题实际上出在我用作包装器的 HTML 代码上。

    let htmlWrapperString = "<html><head>\n<style type=\"text/css\">body {font-family: \"%@\"; font-size: %@;-webkit-text-size-adjust: none;}</style></head><body><div id=\"cnt\">%@</div></body></html>"
    

    所以在正文中没有包裹 div 之前,当我查询正文标记的高度时,它总是返回整个视口大小,而不仅仅是正文中的文本高度。

    现在它可以可靠地工作了。

    【讨论】:

    • 我仍然不明白为什么你希望内容高度影响 webview 的高度?如果您的 webview 比内容小,它有自己的滚动视图自动用于滚动内容。
    • 我需要在 Web 视图中显示可变数量的 HTML 格式文本,这意味着我希望它的外观和行为就像一个标签。我禁用了 Web 视图的滚动功能。所以整个视图是可滚动的,而不仅仅是 web 视图。 Storyboard 从图片中应该可以看出我需要实现什么。
    • 好的,那么外部滚动视图确实有意义。不过,您需要禁用 webview 的内部滚动视图的滚动,并且可能禁用整个视图的用户交互。然后,假设您控制显示的内容(即,它不是任意网站),它甚至可能运行得相当好;在我们的应用程序(“随机 - 应用程序”)中,我们实际上使用了类似的技巧来显示内容预览卡,只是它不是滚动视图,而是带有平移手势识别器的自定义视图。您还可以通过在更改大小时以可预测的方式设计 CSS 来帮助自己。
    【解决方案2】:

    首先,如果代码真的如图所示,你就是将内容的width赋给height常量。这肯定会导致问题。 (显然它不是如图所示;请显示实际代码,而不是在问题中输入新的“相似”代码……)

    其次,仅在webViewDidFinishLoad 中检测内容高度并不是一种非常可靠的方法。在某些网站上,实际调用它可能需要很长时间,但内容可能仍然可用,当然用户在浏览器中的任何操作都可能会改变它,并且许多网站会在页面末尾附加更多内容苍蝇(例如,当用户向下滚动时)。

    另外,我希望您意识到scrollView.contentSize 是内容本身的大小(不是可见部分),并且它的高度不会随着旋转而改变,除非宽度以一种使内容布局发生变化的方式发生变化.

    总的来说,我认为您可能正在尝试做一些UIWebView 根本不适合的事情。您应该只自动布局 webview 本身的大小,而不是将其放在外部 UIScrollView 中(如果我正确阅读了标题并且这就是您正在做的事情)。然后它的内部scrollView 将自动为您处理内容滚动,而不是与您的外部scrollView 冲突。如果您需要对来自内部滚动视图的事件等做出反应,您可以将自己设置为内部滚动视图的代表。

    要在旋转时调整UIWebView 本身的大小,请设置约束以绑定从其每个边缘到周围视图的距离(或使用更简单的autoresizingMask)。在didRotateFromInterfaceOrientation 中应该不需要做任何事情(如果您确实需要手动布局,请在viewWillLayoutSubviews 和/或viewDidLayoutSubviews 中进行)。

    【讨论】:

    • 感谢您的回复。第一部分只是一个错字,不是导致问题的原因,我只是在复制代码时忘记修复它(我会更正它,以免造成混淆)。我确实意识到 contentSize 是实际内容的大小。当屏幕旋转时,高度会发生变化。但它从来没有,这就是为什么我总是创建新的 WebViews,因为它第一次进行大小调整时,它得到了半正确的。但是在我发布问题后我设法找到了解决方案(这总是发生在我身上!)我会尽快发布。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    相关资源
    最近更新 更多