【问题标题】:How to adjust WKWebview's container content height to the webview content?如何将 WKWebview 的容器内容高度调整为 webview 内容?
【发布时间】:2019-06-16 23:44:46
【问题描述】:

我正在尝试获取我的WKWebview 内容的正确高度和宽度,以将 webview 容器高度设置为 webview 内容。 我已经尝试了很多关于堆栈溢出的解决方案。

使用此代码,容器具有正确的高度,但是 webview 的宽度太大(好像 webview 被缩放了)

override func viewDidLoad() {

    let webConfiguration = WKWebViewConfiguration()
    let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: 0.0, height: self.viewForWebview.frame.size.height))
    self.webView = WKWebView (frame: customFrame , configuration: webConfiguration)
    webView.translatesAutoresizingMaskIntoConstraints = false
    self.viewForWebview.addSubview(webView)

    NSLayoutConstraint.activate([
         self.webView.topAnchor.constraint(equalTo: self.viewForWebview.topAnchor),
        self.webView.bottomAnchor.constraint(equalTo: self.viewForWebview.bottomAnchor),
        self.webView.leadingAnchor.constraint(equalTo: self.viewForWebview.leadingAnchor),
        self.webView.trailingAnchor.constraint(equalTo: self.viewForWebview.trailingAnchor)
        ])

    webView.uiDelegate = self
     webView.navigationDelegate = self
     webView.scrollView.isScrollEnabled = false

    let bodyHtml = "<html><head><meta name=\"viewport\" content=\"initial-scale=1.0\" />" + htmlString + "</body></html>";  
    webView.loadHTMLString(bodyHtml, baseURL: Bundle.main.resourceURL)
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

    self.heightWebviewConstraint.constant = self.webView.scrollView.contentSize.height
    self.view.setNeedsLayout()
    self.view.setNeedsUpdateConstraints()
}

除了添加&lt;head&gt;标签,我也尝试使用evaluateJavaScript,但是在这种情况下,高度的容器太大了,而webview的宽度也太大了。

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

    self.webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
        if complete != nil {
                self.webView.evaluateJavaScript("document.body.offsetHeight", completionHandler: { (height, error) in

                self.heightWebviewConstraint.constant = height as! CGFloat
                self.view.setNeedsLayout()
                self.view.setNeedsUpdateConstraints()
            })
        }

    })
}

我还尝试添加特定的css样式(没有viewport和没有evaluateJavaScript),在这种情况下webview的宽度还可以,但是高度的容器太小(我的webview在顶部和底部被裁剪)。

let bodyHtml = "<html><head> <style>  img {  width:auto; height:auto;  max-width:100%; </style></head><body>" + htmlString + "</body></html>"

我迷失了所有这些解决方案。

【问题讨论】:

    标签: ios swift webview height wkwebview


    【解决方案1】:

    我认为您实际上非常接近那里的解决方案。我遇到了类似的问题,并设法通过评估 javascript 来解决它。我们的实现有点不同,因为我们使用带有嵌套 WkWebViews 的堆栈视图作为排列的子视图。但我可以分享我们的代码(去掉 stackview 部分),你可以自己尝试一下。

        func addAndLoadWebView(with url: URL) {
             let wkWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 100))
             wkWebView.translatesAutoresizingMaskIntoConstraints = false
             wkWebView.navigationDelegate = self
             wkWebView.scrollView.isScrollEnabled = false
             wkWebView.scrollView.bounces = false
             wkWebView.scrollView.bouncesZoom = false
             wkWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
             self.view.addSubview(wkWebView)
             wkWebView.load(URLRequest(url: url))
        }
    
        @available(iOS 12.0, *)
        func asyncGetHTMLHeight(_ webview: WKWebView, completion: @escaping (CGFloat) -> Void) {
            webview.evaluateJavaScript("document.body.offsetHeight") { (result, _) in
                guard let result = result as? CGFloat else {
                    completion(0.0)
                    return
                }
                completion(result)
            }
        } 
    
        @available(iOS 12.0, *)
        func compatibleMeasureImageContent(with webview: WKWebView) {
        webview.evaluateJavaScript("document.body.firstChild.offsetHeight") { (result, _) in
            guard let result = result as? CGFloat else {
                return
            }
            var height = result
            webview.evaluateJavaScript("document.body.firstChild.width") { (result, _) in
                guard let width = result as? CGFloat else {
                    return
                }
                // do something with width and height here
                // in our case images come 1 by one since our html is delivered in parts. You might have to check each image tag for its height for this calculation to work.
                }
            }
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
             self.asyncGetHTMLHeight(webView, completion: { newHeight in
                 webView.frame.size.height = newHeight
                 webView.removeConstraints(webView.constraints)
                 webView.heightAnchor.constraint(equalToConstant: newHeight).isActive = true          
              })
        }
    

    【讨论】:

    • 对我不起作用,新结果:高度的容器太大,而网络视图的宽度太小:(
    • 您是在严格加载 html 还是 PDF?
    • 意识到我们实际上在代码注入之前添加了一些 HTML 规范化。不确定它是否有帮助,但也可以链接它。
    • html 里面只有 标签
    • 嗯图片有点棘手,您可能需要编写一些 javascript 来检查每个图片标签。实际上,我们对图像的高度计算方式不同。
    猜你喜欢
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多