SwiftUI - WebView

问题描述 投票:0回答:1

对 SwiftUI 相当陌生,所以提前谢谢您。在 Coordinator 的 init 内部,我们传递 WebView 让 Coordinator 知道父级是谁,但是 WebView 是一个结构体,Coordinator 不会拥有 WebView 的新副本而不是原始 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 swift3 wkwebview
1个回答
0
投票

是的,

Coordinator
持有原版
WebView
的副本,你理解得没错。但它的目的并不是你想象的那样。

首先,您需要了解

WebView
并不包含
WKWebView
,其目的是提供如何更新
WKWebView
以满足您的意图的信息,而
Coordinator
则通过保留
WebView
的副本来帮助它

有什么帮助?通常跟踪

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)")
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.