【发布时间】:2021-10-27 16:27:29
【问题描述】:
我想使用 SwiftUI 在视图中制作一个非常简单的浏览器。
会发生什么:
在我的 ContentView 中,有一个 WKWebView,导航栏左侧有一个“返回”按钮。如果按下“返回”按钮,webView 将返回上一页。
ContentView.swift:
struct ContentView: View {
let defaultUrl = "https://www.apple.com"
@State var needsGoBack = false
var body: some View {
WebView(urlString: defaultUrl, needsGoBack: $needsGoBack)
.navigationBarItems(leading:
Button(action: {
print("button pressed...set needsGoBack = true")
needsGoBack = true
}) {
Text("Go Back")
})
}
}
WebView.swift
struct WebView: UIViewRepresentable {
let urlString: String
let navigationHelper = WebViewHelper()
@State var myWebView = WKWebView()
@Binding var needsGoBack: Bool
func makeUIView(context: Context) -> WKWebView {
if let url = URL(string: urlString) {
let request = URLRequest(url: url)
myWebView.load(request)
}
myWebView.navigationDelegate = navigationHelper
myWebView.uiDelegate = navigationHelper
return myWebView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
print("webview updateUIView")
print("needsGoBack", needsGoBack)
if needsGoBack {
myWebView.goBack()
needsGoBack = false // this line has problem
}
}
typealias UIViewType = WKWebView
}
// https://gist.github.com/joshbetz/2ff5922203240d4685d5bdb5ada79105
class WebViewHelper: NSObject, WKNavigationDelegate, WKUIDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("webview didFinishNavigation")
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("didStartProvisionalNavigation")
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
print("webviewDidCommit")
}
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("didReceiveAuthenticationChallenge")
completionHandler(.performDefaultHandling, nil)
}
}
实际发生的情况:
在WebView.swift的updateUIView函数中,有一条警告信息“Modifying state during view update, this will cause undefined behavior”。对于这行代码:“needsGoBack = false”。并且“needsGoBack”变量不会设置为“false”。 “返回”按钮首次工作。但是,因为“needsGoBack”之后总是“true”,所以不会第二次通知子视图(WebView)(调用updateUIView方法)。
【问题讨论】: