swiftui WKWebView加载html字符串高度自适应
在SwiftUI中使用WKWebView加载HTML字符串并进行高度自适应的方法如下:
- 首先,你需要在你的SwiftUI视图中创建一个自定义的UIViewRepresentable类,用来表示WKWebView。在该类中,你需要实现makeUIView和updateUIView两个方法。
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
let htmlString: String
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.loadHTMLString(htmlString, baseURL: nil)
}
}
- 接下来,在你的SwiftUI视图中使用该自定义的WebView。
struct ContentView: View {
let htmlString = """
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style>
body {
font-size: 16px;
line-height: 1.2;
padding: 16px;
}
</style>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is a sample HTML string.</p>
</body>
</html>
"""
var body: some View {
ScrollView {
WebView(htmlString: htmlString)
.frame(height: 1)
.onPreferenceChange(WebViewHeightPreferenceKey.self) { height in
// 更新WebView的高度
}
}
}
}
- 为了实现高度自适应,你可以使用一个PreferenceKey来获取WebView的内容高度,并将其传递给父视图。首先,创建一个PreferenceKey来保存WebView的高度。
struct WebViewHeightPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
- 在WebView中添加一个WKNavigationDelegate来获取WebView的内容高度,并将其传递给父视图。
struct WebView: UIViewRepresentable {
let htmlString: String
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.loadHTMLString(htmlString, baseURL: nil)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.readyState") { result, error in
if let _ = result {
webView.evaluateJavaScript("document.body.scrollHeight") { result, error in
if let height = result as? CGFloat {
self.parent.height = height
}
}
}
}
}
}
}
- 最后,使用GeometryReader和PreferenceKey来动态更新WebView的高度。
struct ContentView: View {
@State private var webViewHeight: CGFloat = 0
let htmlString = """
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style>
body {
font-size: 16px;
line-height: 1.2;
padding: 16px;
}
</style>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is a sample HTML string.</p>
</body>
</html>
"""
var body: some View {
GeometryReader { geometry in
ScrollView {
WebView(htmlString: htmlString)
.frame(height: webViewHeight)
.background(GeometryReader { webViewGeometry in
Color.clear
.preference(key: WebViewHeightPreferenceKey.self, value: webViewGeometry.size.height)
})
.onPreferenceChange(WebViewHeightPreferenceKey.self) { height in
self.webViewHeight = height
}
}
.frame(height: geometry.size.height)
}
}
}
这样,WebView会根据内容的高度进行自适应,并且可以在父视图中进行滚动
原文地址: https://www.cveoy.top/t/topic/h6Ma 著作权归作者所有。请勿转载和采集!