Reputation: 4495
I'm having a hard time to understand the code below. If you look at my comments, I'm trying to change a binding variable in different parts of the code, but it's only working in the WKWebView events functions in the Coordinator.
Why doesn't the variable change when I try to do so in other parts of the code?
import Cocoa
import SwiftUI
import WebKit
import PlaygroundSupport
struct InternalBrowser: NSViewRepresentable {
var webView: WKWebView = WKWebView()
@Binding var status: String
func makeNSView(context: Context) -> WKWebView {
self.webView.load(URLRequest(url: URL(string: "https://www.google.com")!))
self.webView.navigationDelegate = context.coordinator
// THIS WON'T CHANGE THE BINDING VARIABLE
self.status = "makeNSView"
return self.webView
}
func updateNSView(_ nsView: WKWebView, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: InternalBrowser
init(parent: InternalBrowser) {
self.parent = parent
// THIS WON'T CHANGE THE BINDING VARIABLE
self.parent.status = "Coordinator:: init"
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
// THIS WORKS
self.parent.status = "LOADING"
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// THIS WORKS
self.parent.status = "LOADED"
}
}
}
struct Browser: View {
@State var status = "STATUS"
var body: some View {
VStack {
InternalBrowser(status: self.$status).frame(width: 400, height: 400)
Text(self.status)
}
}
}
PlaygroundPage.current.setLiveView(Browser().frame(width: 500, height: 500))
Upvotes: 1
Views: 189
Reputation: 257719
Why doesn't the variable change when I try to do so in other parts of the code?
@Binding
affects corresponding @State
which itself results in corresponding View rebuild, but(!) NSViewRepresentable.makeNSView
and Coordinator.init
are called during(!) View rebuild... so, changing state during view rebuild cause new view rebuild, which comes to new change of state... cycle. Such situations are handled by SwiftUI rendering engine and ... such state changes are ignored. This is what you see.
Upvotes: 1