【发布时间】:2020-03-08 09:58:24
【问题描述】:
所以我将WKWebView 包装在UIViewRepresentable 中并构建了一个协调器以访问其导航委托的功能。在webView(_:didFinish:) 函数中,我试图更新视图的didFinishLoading 变量。如果我在分配后立即打印,它会打印 true - 预期的行为。但是,在父视图中,当我调用 getHTML 函数时,它会打印 false - 即使我等到 WKWebView 完全加载。
代码如下:
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
@Binding var link: String
init(link: Binding<String>) {
self._link = link
}
private var didFinishLoading: Bool = false
let webView = WKWebView()
func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
self.webView.load(URLRequest(url: URL(string: self.link)!))
self.webView.navigationDelegate = context.coordinator
return self.webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
return
}
class Coordinator: NSObject, WKNavigationDelegate {
private var webView: WebView
init(_ webView: WebView) {
self.webView = webView
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("WebView: navigation finished")
self.webView.didFinishLoading = true
}
}
func makeCoordinator() -> WebView.Coordinator {
Coordinator(self)
}
func getHTML(completionHandler: @escaping (Any?) -> ()) {
print(self.didFinishLoading)
if (self.didFinishLoading) {
self.webView.evaluateJavaScript(
"""
document.documentElement.outerHTML.toString()
"""
) { html, error in
if error != nil {
print("WebView error: \(error!)")
completionHandler(nil)
} else {
completionHandler(html)
}
}
}
}
}
struct WebView_Previews: PreviewProvider {
@State static var link = "https://apple.com"
static var previews: some View {
WebView(link: $link)
}
}
【问题讨论】:
-
你的 WebView 是结构,所以很有价值,所以它被复制到你的 Coordinator 中。
-
@Asperi 哦,对了......忘了我在一个结构中。有什么办法可以通过引用传递它吗?
inout在这里不适用,因为它会使makeCoordinator发生变异,因此它不符合UIViewRepresentable协议 -
一般来说,我倾向于将视图模型推荐为来自 Combine 的 ObservableObject 的子类,并在 SwifthUI 结构之间到处传递它的实例作为参考。
-
@Asperi 但它仍然会使函数可变
-
在下面的代码中查看我的意思