iOS development talk WKWebView dynamically obtains the height of the web page

        Recently, I encountered a requirement during project development. The analyst information at the top of an article, the comments and replies at the bottom, and the text box information are displayed natively, and the main content in the middle is displayed using H5 made by the Vue framework. The only problem encountered here is to dynamically calculate the height of the H5 web page so that the page is consistent as a whole and there will be no gesture conflicts. The overall effect is as follows:

After sorting out the search data, there are basically two ideas. One is to obtain the scrollHeight of the page by injecting Js script into didFinish, and the other is to monitor the value of contentSize through the KVO mode of iOS (there are also ways to inject Js to monitor, which is difficult to operate). Tested on different web pages and different systems, the KVO mode can achieve the requirements and is highly accurate. The main reference codes are now listed as follows:

1. Define WKWebView and add contentSize listener

import WebKit

private let content_size_key = "contentSize"
private let ScreenWidth: CGFloat = UIScreen.main.bounds.size.width

private lazy var wkWebView:WKWebView = {[unowned self] in
        let _wk = WKWebView.init(frame: .zero)

        //监听
        _wk.scrollView.addObserver(self,
                                  forKeyPath: content_size_key,
                                  options: NSKeyValueObservingOptions.new, context: nil)
        
        return _wk
}()

2. Implement monitoring and storage height value

//MARK: - KVO 监听
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        //根据内容的高重置webView视图的高度
        guard let webCGSize = change?[NSKeyValueChangeKey.newKey] as? CGSize  else {
            return
        }

        //[S] 此处代码是处理在iOS13.6中 contentSize 高度偏高产生大量空白的
        var _h:CGFloat = webCGSize.height
        if webCGSize.width > ScreenWidth {
            _h = (ScreenWidth / webCGSize.width) * _h
        }
        //[E]
        
        if !self.arrHeights.contains(_h) {
            self.arrHeights.append(_h)
        }
    }

3. Update UI

private lazy var arrHeights = [CGFloat]() {
   didSet{
       if self.arrHeights.count > 0 {
           if let _h = self.arrHeights.sorted(by: { return $0 > $1 }).first {
               self.updateWebViewFor(Height: _h)
            }
        }
   }
}

/// 更新高度(也有通过约束来更新,殊途同归)
/// - Parameter h: CGFloat
func updateWebViewFor(Height h:CGFloat){
        
    DispatchQueue.main.async {
          var rect = self.wkWebView.frame
          rect.size.height = h
          self.wkWebView.frame = rect
            
          //headView是UITableView 的 tableHeaderView
          //wkWebView 是headView的一部分
          rect = self.headView.frame
          rect.size.height = SpecialColumnMainView.section_head_height2 + 30 + h
          self.headView.frame = rect
            
          self.listTableView.reloadData()
    }
}

4. Destroy and remove monitoring

    deinit {
        self.wkWebview.scrollView.removeObserver(self, forKeyPath: content_size_key, context: nil)
    }

In addition, there are a large number of KVO monitoring contentSize problems on the Internet that are highly inaccurate. This has been solved in this article. Please see the notes in the article for details.

There is a prerequisite for accurately obtaining the height of an H5 webpage, which is to prevent the height of the webpage from collapsing. For details, please refer to:https://blog.csdn.net/weixin_39851592/article/details/ 83622716

This article is over. For the OC version, you can follow this operation. If you have any questions, you can leave a message for consultation.

Guess you like

Origin blog.csdn.net/yimiyuangguang/article/details/114639474