Mac OS Swift UI 中使用WKWebView,以及实现代理

Mac OS Swift UI 中使用WKWebView,以及实现代理

项目配置

首先进行项目配置,支持入网
​​​​​​​​在这里插入图片描述
在这里插入图片描述

包装webView

首先为了能在Swift UI中使用WebView,应该对其进行包装

struct WebView: NSViewRepresentable {
    
    

    let webView: WKWebView

    func makeNSView(context: Context) -> WKWebView {
    
     return webView }
    
    func updateNSView(_ nsView: WKWebView, context: Context) {
    
     }
}

实现代理

class WebViewNavigationDelegate: NSObject, WKNavigationDelegate {
    
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    
    
        // TODO
        decisionHandler(.allow)
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    
    
        // TODO
        decisionHandler(.allow)
    }
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    
    
        
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    
    
        
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    
    
        
    }
}

自定义webView

观察网页在什么时候需要前进或者后退,这个时候要用ObservableObject来进行包装

class CustomWebView: ObservableObject {
    
    
    let webView: WKWebView

    private let navigationDelegate: WebViewNavigationDelegate

    init() {
    
    
        let configuration = WKWebViewConfiguration()
        configuration.websiteDataStore = .nonPersistent()
        webView = WKWebView(frame: .zero, configuration: configuration)
        navigationDelegate = WebViewNavigationDelegate()

        webView.navigationDelegate = navigationDelegate
        setupBindings()
    }

    @Published var urlString: String = "https://www.csdn.net/"
    @Published var canGoBack: Bool = false
    @Published var canGoForward: Bool = false
    @Published var isLoading: Bool = false

    private func setupBindings() {
    
    
        webView.publisher(for: \.canGoBack)
            .assign(to: &$canGoBack)

        webView.publisher(for: \.canGoForward)
            .assign(to: &$canGoForward)

        webView.publisher(for: \.isLoading)
            .assign(to: &$isLoading)

    }

    func loadUrl() {
    
    
        guard let url = URL(string: urlString) else {
    
    
            return
        }

        webView.load(URLRequest(url: url))
    }

    func goForward() {
    
    
        webView.goForward()
    }

    func goBack() {
    
    
        webView.goBack()
    }
}

调试

现在,可以将它放到contentView中调试

struct ContentView: View {
    
    
    
    @StateObject var model = CustomWebView()
    
    var body: some View {
    
    
        ZStack(alignment: .bottom) {
    
    
            Color.black
                .ignoresSafeArea()
            
            VStack(spacing: 0) {
    
    
                HStack(spacing: 10) {
    
    
                    HStack {
    
    
                        TextField("Input an url",
                                  text: $model.urlString)
                            .disableAutocorrection(true)
                            .padding(10)
                        Spacer()
                    }
                    .background(Color.white)
                    .cornerRadius(30)
                    
                    Button("Go", action: {
    
    
                        model.loadUrl()
                    })
                    .foregroundColor(.blue)
                    .padding(10)
                    
                }.padding(10)
                
                ZStack {
    
    
                    WebView(webView: model.webView)
                    
                    if model.isLoading {
    
    
                        ProgressView()
                            .progressViewStyle(CircularProgressViewStyle())
                    }
                }
            }
        }
        .toolbar {
    
    
            ToolbarItemGroup(placement: .navigation) {
    
    
                Button(action: {
    
    
                    model.goBack()
                }, label: {
    
    
                    Image(systemName: "arrowshape.turn.up.backward")
                })
                .disabled(!model.canGoBack)
                
                Button(action: {
    
    
                    model.goForward()
                }, label: {
    
    
                    Image(systemName: "arrowshape.turn.up.right")
                })
                .disabled(!model.canGoForward)
                
                Spacer()
            }
        }
    }
}

最终效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/quanhaoH/article/details/125663607