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

SwiftUI中WKWebView自适应高度及字体修改问题

SwiftUI中WKWebView的高度适配与字体修改方案

1. 让WebView自动收缩至最小高度

核心思路是通过WKWebView加载完成后获取内容实际高度,将高度值绑定回SwiftUI视图,动态调整WebView的布局高度。

封装带高度绑定的WKWebView

import SwiftUI
import WebKit

struct HTMLWebView: UIViewRepresentable {
    let htmlString: String
    @Binding var webViewHeight: CGFloat
    
    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.navigationDelegate = context.coordinator
        // 禁用内部滚动,避免和外部布局冲突
        webView.scrollView.isScrollEnabled = false
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.loadHTMLString(htmlString, baseURL: nil)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: HTMLWebView
        
        init(_ parent: HTMLWebView) {
            self.parent = parent
        }
        
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            // 执行JS获取内容高度
            webView.evaluateJavaScript("document.body.scrollHeight") { result, error in
                if let height = result as? CGFloat {
                    DispatchQueue.main.async {
                        self.parent.webViewHeight = height
                    }
                }
            }
        }
    }
}

在SwiftUI视图中使用

struct ContentView: View {
    @State private var webViewHeight: CGFloat = 0
    let htmlContent = "<p>这是一段自适应高度的HTML内容</p><p>多行文本测试,高度会自动收缩到内容所需最小值</p>"
    
    var body: some View {
        VStack {
            HTMLWebView(htmlString: htmlContent, webViewHeight: $webViewHeight)
                .frame(height: webViewHeight)
            TextWebView下方的其他内容")
        }
        .padding()
    }
}

2. 修改WebView的字体

提供两种实用方案,按需选择:

方案一:直接修改HTML内容,注入CSS样式

在HTML字符串头部添加<style>标签,直接指定字体、字号等样式,灵活性最高:

let htmlContent = """
<style>
body {
    font-family: "PingFang SC", "Helvetica Neue", sans-serif;
    font-size: 16px;
    margin: 0;
    padding: 0;
}
p {
    margin: 4px 0;
}
</style>
<p>修改字体后的HTML内容示例</p>
"""

方案二:通过WKWebViewConfiguration注入脚本

如果无法直接修改HTML内容,可通过注入JS脚本动态修改样式:

func makeUIView(context: Context) -> WKWebView {
    let config = WKWebViewConfiguration()
    // 创建用户脚本,在DOM加载完成后修改字体
    let script = WKUserScript(
        source: """
        document.body.style.fontFamily = 'PingFang SC, Helvetica Neue, sans-serif';
        document.body.style.fontSize = '16px';
        """,
        injectionTime: .atDocumentEnd,
        forMainFrameOnly: true
    )
    config.userContentController.addUserScript(script)
    
    let webView = WKWebView(frame: .zero, configuration: config)
    webView.navigationDelegate = context.coordinator
    webView.scrollView.isScrollEnabled = false
    return webView
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:17:40