SwiftUI - WebView

SwiftUI - WebView

提问人:bubu 提问时间:8/31/2023 最后编辑:bubu 更新时间:9/1/2023 访问量:64

问:

对 SwiftUI 相当陌生,所以提前感谢您。在 Coordinator 的 init 中,我们传递 WebView 让 Coordinator 知道谁是父级,但 WebView 是一个结构,Coordinator 不会拥有 WebView 的新副本而不是原始副本吗?

如果是这样,为什么经常提到这种方法?创建一个新类(ObservableObject)并让 WebView 创建该类的对象并将该类传递给 Coordinator 会更好吗?

   struct WebView: UIViewRepresentable {
    var url: URL

    func makeCoordinator() -> WebView.Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> WKWebView {
        let view = WKWebView()
        view.navigationDelegate = context.coordinator
        view.load(URLRequest(url: url))
        return view
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {}

    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebView

        init(_ parent: WebView) {
            self.parent = parent
        }
    }
}
SWIFTUI的 斯威夫特3 wkwebview的

评论

0赞 Yrb 8/31/2023
WKWebView是一个类,而不是一个结构。您正在传递引用。
0赞 bubu 8/31/2023
对不起,@Yrb,我已经编辑了这个问题,我的意思是问编辑过的问题 - 在这种情况下,我们正在传递 WebView,这是一个结构,在各种文章中很常见
0赞 bubu 8/31/2023
例如,stackoverflow.com/questions/59382225/...medium.com/@mdyamin/swiftui-mastering-webview-5790e686833e developer.apple.com/forums/thread/126986 - 我们看到它传递了结构本身

答:

1赞 meomeomeo 9/1/2023 #1

是的,持有原件的副本,你没看错。但它的目的不是你想的那样。CoordinatorWebView

首先,您需要了解 不成立 ,其目的是提供信息 如何更新以适应您的意图,并通过保留副本来帮助它WebViewWKWebViewWKWebViewCoordinatorWebView

它有什么帮助?通常跟踪旧版本(最新版本或第一个版本),以便在需要时获取其信息WebView

func updateUIView(_ uiView: WKWebView, context: Context) {
    let lastURL = context.coordinator.parent.url
    print(lastURL)
    context.coordinator.parent = self // (*)
}
/// be cause of (*), next time lastURL will be the previous URL
/// without (*), lastURL always be the first URL you used to init WKWebView

这是另一个小示例,您可以在预览工作原理上看到UIViewRepresentable

struct LabelView: UIViewRepresentable {
    var text: String
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel(frame: .init(x: 0, y: 0, width: 100, height: 100))
        label.text = text
        return label
    }
    
    func updateUIView(_ uiView: UILabel, context: Context) {
        let lastLabel = context.coordinator.parent.text
        uiView.text = "\(lastLabel) -> \(text)"
        context.coordinator.parent = self
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: LabelView

        init(_ parent: LabelView) {
            self.parent = parent
        }
    }
}
struct TestLabelView: View {
    @State private var num = 0
    var body: some View {
        Button { num += 1 } label: {
            LabelView(text: "\(num)")
        }
    }
}

评论

0赞 bubu 9/1/2023
完美解释,谢谢@meomeomeo