为什么状态变量在此Swift代码的某些部分中没有改变?

时间:2020-07-26 05:18:43

标签: swiftui

我很难理解下面的代码。如果您看一下我的评论,我正在尝试在代码的不同部分更改绑定变量,但是它仅在Coordinator的WKWebView事件函数中起作用。

当我尝试在代码的其他部分进行更改时,为什么变量没有更改?

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))

1 个答案:

答案 0 :(得分:1)

当我尝试在代码的其他部分进行更改时,为什么变量没有更改?

@Binding影响相应的@State,它本身会导致相应的View重建,但是(!)NSViewRepresentable.makeNSViewCoordinator.init在View!rebuild期间被称为... ,在视图重建期间更改状态会导致新视图重建,从而带来新的状态更改...周期。此类情况由SwiftUI呈现引擎处理,并且...状态更改被忽略。这就是您所看到的。