SwiftUI KVO 监听 WebView 高度:使用 @State 和 onChange
在 SwiftUI 中,可以使用'@State'属性包装器来创建一个可观察的属性,然后通过'onChange'修饰符来监听属性的变化。
假设你的 WebView 高度是由一个名为'webViewHeight'的属性控制,你可以这样实现 KVO 监听:
import SwiftUI
import WebKit
struct ContentView: View {
@State private var webViewHeight: CGFloat = .zero
var body: some View {
VStack {
WebView(webViewHeight: $webViewHeight)
.frame(height: webViewHeight)
}
.onChange(of: webViewHeight) { newValue in
// 这里可以处理 WebView 高度变化后的逻辑
print("WebView 高度变化为:(newValue)")
}
}
}
struct WebView: UIViewRepresentable {
@Binding var webViewHeight: CGFloat
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
webView.scrollView.isScrollEnabled = false
webView.scrollView.bounces = false
webView.addObserver(self, forKeyPath: "scrollView.contentSize", options: .new, context: nil)
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
// 更新 WebView 内容
}
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 加载完成后更新 WebView 高度
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
if let height = height as? CGFloat {
DispatchQueue.main.async {
self.parent.webViewHeight = height
}
}
})
}
})
}
}
}
在上述示例中,'ContentView' 中的 'webViewHeight' 被声明为'@State' 属性,然后通过'onChange' 修饰符监听属性的变化。'WebView' 结构体中的 'webViewHeight' 通过'@Binding' 属性包装器与 'ContentView' 中的属性进行绑定。
在 'WebView' 的 'makeUIView' 方法中,我们创建了一个 'WKWebView' 实例,并通过 'addObserver(_:forKeyPath:options:context:)' 方法注册了一个观察者来监听 'scrollView.contentSize' 属性的变化。
在 'Coordinator' 的 'webView(:didFinish:)' 方法中,我们通过 'evaluateJavaScript(:completionHandler:)' 方法来获取 WebView 的内容高度,并将其更新到 'WebView' 的 'webViewHeight' 属性中。
当 'webViewHeight' 属性发生变化时,'onChange' 修饰符会调用相关的闭包,并执行相应的逻辑。在这个例子中,我们只是简单地打印了 WebView 的高度变化。你可以根据自己的需求来处理 WebView 高度变化后的逻辑。
原文地址: https://www.cveoy.top/t/topic/pUWi 著作权归作者所有。请勿转载和采集!