SwiftUI:WKWebView 未加载 [英] SwiftUI: WKWebView not loading

查看:44
本文介绍了SwiftUI:WKWebView 未加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 SwiftUI 应用程序中有一个 WKWebView 作为 UIViewRepresentable,它最初可以工作.网页已加载,我可以导航到其他页面.如果我强制 Web 视图加载另一个页面,则不会发生任何事情.它适用于 Xcode 11.3,但似乎从 11.4 开始就被破坏了.这是一个例子.重新加载强制随机加载页面 1 或 2.任何建议可能是什么问题?

I have a WKWebView as UIViewRepresentable in my SwiftUI application and it works initially. The webpage is loaded and I can navigate to other pages. If I force the web view to load another page nothing happens. It worked with Xcode 11.3 but seems to be broken since 11.4. Here is an example. Reload forces to load page 1 or 2 by random. Any suggestion what might be the problem?

import WebKit
import SwiftUI

struct WebView: UIViewRepresentable{

    var url: URL

    let urls = [URL(string: "https://google.com/")!, URL(string: "https://bing.com")!]

    private let webview = WKWebView()

    fileprivate func loadRequest() {

        let index = Int(Date().timeIntervalSince1970) % 2
        print(index)

        let request = URLRequest(url: urls[index])
        webview.load(request)
    }

    func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {

        loadRequest()

        return webview
    }

    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {}

    func reload(){
        loadRequest()
    }

}

WebView 是这样使用的(简化示例):

The WebView ist used this way (simplified example):

 var body: some View {
        VStack{
            Button(action: {
                self.webView.reload()
            }){
                Text("reload")
            }
            webView
        }
}

事情有点复杂.重新加载是由操作表触发的,似乎也有问题.请参阅我的带有操作表的简化示例:

Things are bit more complicated. The reloading is triggered by an action sheet and there seems to be a problem as well. Please see my simplified example with an action sheet:

@State private var showingSheet = false
 @State private var shouldRefresh = false
    var body: some View {

            ZStack{

                WebView(url: url, reload: $shouldRefresh)
                    .padding(paddingEdgeInsets())
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
                    .edgesIgnoringSafeArea(.all)

                Button(action: {
                    self.showingSheet = true
                }){
                    Text("Show sheet")
                }



            }.actionSheet(isPresented: $showingSheet) {
                ActionSheet(title: Text("OPTIONS"), buttons: [
                    .default(Text("RELOAD"), action: {
                        self.shouldRefresh = true
                    }), .default(Text("EXIT"), action: {
                        self.presentationMode.wrappedValue.dismiss()
                    }), .cancel()])
            }
        }

推荐答案

您尝试将 'reference'-base 方法应用于基于值的 SwiftUI 视图.这是不允许的,所以不起作用.在按钮操作和下面的使用代码 webView 中是不同的独立值(因为 WebView 是结构).

You try to apply 'reference'-base approach to value based SwiftUI views. It is not allowed, so does not work. In your usage code webView in button action and in below are different independent values (because WebView is struct).

所以这是可能的方法.使用 Xcode 11.4/iOS 13.4 测试

So here is possible approach. Tested with Xcode 11.4 / iOS 13.4

struct TestWebView: View {
    @State private var shouldRefresh = false
    var body: some View {
        VStack{
            Button(action: {
                self.shouldRefresh = true
            }){
                Text("Reload")
            }
            WebView(url: nil, reload: $shouldRefresh)
        }
    }
}


struct WebView: UIViewRepresentable{

    var url: URL?     // optional, if absent, one of below search servers used
    @Binding var reload: Bool

    private let urls = [URL(string: "https://google.com/")!, URL(string: "https://bing.com")!]
    private let webview = WKWebView()

    fileprivate func loadRequest(in webView: WKWebView) {
        if let url = url {
            webView.load(URLRequest(url: url))
        } else {
            let index = Int(Date().timeIntervalSince1970) % 2
            webView.load(URLRequest(url: urls[index]))
        }
    }

    func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
        loadRequest(in: webview)
        return webview
    }

    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
        if reload {
            loadRequest(in: uiView)
            DispatchQueue.main.async {
                self.reload = false     // must be async
            }
        }
    }
}

这篇关于SwiftUI:WKWebView 未加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆