如何让TableViewController头部的WKWebView自适应内容高度?
当然可行!我之前在项目里刚好实现过类似的需求,给你分享下具体的实现思路和代码调整方向:
核心思路
要让WKWebView在TableView Header里自动适配内容高度,关键是等WebView内容加载完成后,获取其真实内容高度,再动态调整Header的高度。和UIWebView的思路逻辑一致,但WKWebView需要用更可靠的方式获取高度,并且要配合TableView的布局更新来生效。
具体实现步骤
添加WKNavigationDelegate监听内容加载
只设置WKUIDelegate不够,我们需要监听WebView的加载完成事件,所以要给WebView额外设置navigationDelegate,并实现对应的代理方法来捕获加载完成时机。通过JavaScript获取真实内容高度
WKWebView的scrollView.contentSize有时候会因为页面渲染时机问题出现偏差,最可靠的方式是用JS获取页面的实际高度,比如document.body.scrollHeight或者document.documentElement.scrollHeight。动态更新TableView Header的高度
拿到内容高度后,我们需要更新WebView的高度约束(或者直接调整HeaderView的frame),然后触发TableView的布局刷新,确保Header的高度变化能被正确识别。
调整后的代码示例
首先,给你的ViewController添加WKNavigationDelegate协议,然后在Storyboard里给WebView添加一个高度约束并关联到代码(比如命名为webViewHeightConstraint):
class detailTableViewController: UITableViewController, WKUIDelegate, WKNavigationDelegate { @IBOutlet weak var webView: WKWebView! @IBOutlet weak var webViewHeightConstraint: NSLayoutConstraint! // 新增的WebView高度约束 var data = Data() override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self self.tableView.dataSource = self webView.uiDelegate = self webView.navigationDelegate = self // 新增:设置导航代理 let url = URL(string:"http://myweb.com") let req = URLRequest(url:url!) self.webView!.load(req) self.webView!.scrollView.isScrollEnabled = false } // 新增:监听WebView加载完成事件 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 用JS获取页面实际高度 webView.evaluateJavaScript("document.documentElement.scrollHeight") { [weak self] result, error in guard let self = self, let height = result as? CGFloat, error == nil else { return } // 更新WebView的高度约束 self.webViewHeightConstraint.constant = height // 强制触发布局更新 self.view.layoutIfNeeded() // 刷新TableView Header确保高度生效 self.tableView.tableHeaderView?.layoutIfNeeded() self.tableView.reloadData() } } // 其他原有代码... }
额外注意点
- 如果你的页面包含动态加载的内容(比如延迟加载的图片),
didFinish可能在图片加载前就触发,导致高度计算不准确。这种情况下,可以考虑注入WKUserScript监听页面的resize事件或者图片加载完成事件,再通知Native端更新高度。 - 确保Storyboard里WebView和HeaderView的上下左右约束都正确设置,这样WebView的高度变化会自动传递给HeaderView,无需额外调整HeaderView的约束。
内容的提问来源于stack exchange,提问作者D. Finna

