You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift中如何在输入时动态获取WKWebView的高度

实现WKWebView用户输入时实时获取高度的方案

核心思路是通过注入JS监听网页内容变化事件,触发时主动将最新高度回传给原生侧,比原生轮询的性能更高、响应更及时。


步骤1:初始化WKWebView时配置消息监听通道

初始化WKWebViewConfiguration,添加脚本消息处理器,用于接收JS端传回的高度数据:

import WebKit

class YourViewController: UIViewController, WKScriptMessageHandler {
    private var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let config = WKWebViewConfiguration()
        let userContentController = WKUserContentController()
        // 添加消息监听,名称和JS端保持一致
        userContentController.add(self, name: "contentHeightChange")
        config.userContentController = userContentController
        
        webView = WKWebView(frame: .zero, configuration: config)
        webView.navigationDelegate = self
        view.addSubview(webView)
        // 此处添加你的webview布局代码
    }
    
    // 销毁时移除监听,避免内存泄漏
    deinit {
        webView.configuration.userContentController.removeScriptMessageHandler(forName: "contentHeightChange")
    }
}

步骤2:注入JS监听代码,监听内容变化事件

注入JS代码监听用户输入、DOM结构变动等会触发高度变化的事件,每次事件触发时将当前高度回传给原生:

// 在viewDidLoad中添加如下代码,注入JS脚本
let js = """
// 防抖函数,避免频繁回调
function debounce(func, delay) {
    let timer = null;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(() => func.apply(this, arguments), delay);
    }
}

// 上报高度的方法
const reportHeight = debounce(function() {
    const height = document.body.scrollHeight;
    window.webkit.messageHandlers.contentHeightChange.postMessage(height);
}, 100); // 防抖间隔可自行调整,单位ms

// 监听所有可能触发高度变化的事件
document.addEventListener('input', reportHeight);
document.addEventListener('DOMContentLoaded', reportHeight);
window.addEventListener('resize', reportHeight);

// 监听DOM结构变动,适配非输入触发的内容变化
const observer = new MutationObserver(reportHeight);
observer.observe(document.body, {
    childList: true,
    subtree: true,
    attributes: true
});
"""
let userScript = WKUserScript(source: js, injectionTime: .atDocumentStart, forMainFrameOnly: true)
config.userContentController.addUserScript(userScript)

步骤3:实现WKScriptMessageHandler协议,接收高度回调

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    guard message.name == "contentHeightChange",
          let height = message.body as? CGFloat else { return }
    // 此处拿到实时高度,更新你的布局逻辑
    // 注意:如果高度没有变化,不要重复更新约束,避免布局循环
    print("最新webview高度:\(height)")
}

可选补充:原有加载完成的高度获取逻辑可以保留

你原有didFinish中的高度获取代码可以作为兜底,避免特殊场景下JS事件没有触发导致高度获取异常。


内容的提问来源于stack exchange,提问作者iOS App Developer Swift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 14:54:08