在 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 高度变化后的逻辑。

SwiftUI KVO 监听 WebView 高度:使用 @State 和 onChange

原文地址: https://www.cveoy.top/t/topic/pUWi 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录