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

如何从UIViewRepresentable获取HTML内容的高度值?

获取WKWebView中HTML内容的高度

要获取WebKit加载的HTML内容高度,核心思路是在HTML加载完成后,通过JavaScript获取内容的实际高度,再回调给Swift代码。以下是针对你现有代码的修改方案:

步骤1:添加高度绑定与代理协调器

给HTMLView添加绑定属性传递高度,同时通过Coordinator实现WKWebView导航代理,监听HTML加载完成事件:

struct HTMLView: UIViewRepresentable {
    let htmlContent: String
    // 用于向外传递HTML内容的高度
    @Binding var contentHeight: CGFloat

    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        // 设置导航代理,监听加载完成事件
        webView.navigationDelegate = context.coordinator
        // 禁用滚动(如果不需要用户滚动HTML内容)
        webView.scrollView.isScrollEnabled = false
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        let anuphanRegular = getDataString(otf: "Anuphan-Regular")
        
        // 修正HTML样式,去除默认边距,避免高度计算偏差
        let htmlString = """
        <!doctype html>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <html>
            <head>
                <style>
                    * {
                        margin: 0;
                        padding: 0;
                        box-sizing: border-box;
                    }
                    @font-face {
                        font-family: 'Anuphan';
                        src: url('data:font/otf;base64,\(anuphanRegular)') format('opentype');
                    }
                    body, .container {
                        font-family: 'Anuphan';
                        width: 100%;
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <div class="element">
                        <span class="custom">\(htmlContent)</span>
                    </div>
                </div>
            </body>
        </html>
        """
        
        uiView.loadHTMLString(htmlString, baseURL: nil)
    }

    // 创建协调器,处理WebView的代理事件
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: HTMLView

        init(_ parent: HTMLView) {
            self.parent = parent
        }

        // HTML加载完成后调用
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            // 执行JS获取容器高度,也可替换为document.body.scrollHeight
            webView.evaluateJavaScript("document.querySelector('.container').offsetHeight") { [weak self] result, error in
                guard let height = result as? CGFloat, error == nil else { return }
                // 更新绑定的高度值
                self?.parent.contentHeight = height
            }
        }
    }
}

步骤2:在父视图中使用HTMLView

在SwiftUI视图中声明状态变量存储高度,传入HTMLView并使用高度约束布局:

struct ParentView: View {
    @State private var htmlHeight: CGFloat = 0

    var body: some View {
        VStack {
            HTMLView(htmlContent: "你的HTML内容", contentHeight: $htmlHeight)
                .frame(height: htmlHeight) // 用获取到的高度固定WebView框架
            Text("HTML内容高度:\(htmlHeight)")
        }
    }
}

关键细节说明

  • HTML样式修正:给全局元素、body和容器添加margin:0、padding:0,消除浏览器默认样式的高度偏差;添加viewport标签适配移动端宽度。
  • JS高度获取选项:根据HTML结构选择合适的JS表达式:
    • document.body.scrollHeight:获取整个body的滚动高度
    • document.querySelector('.container').offsetHeight:获取指定容器的实际高度
    • document.documentElement.offsetHeight:获取整个HTML文档的高度
  • 禁用滚动:不需要用户滚动时,关闭WebView滚动功能,避免影响布局逻辑。

内容的提问来源于stack exchange,提问作者Mixko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:15:27