webview - 在 SwiftUI 中加载网站时加载事件指示器

标签 webview swiftui xcode11 uiactivityindicatorview

我有一个显示 WebView 的基本列表。我想添加一个在网页加载时显示的事件指示器。这是我创建的代码。

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    var url: String

    // makeUIView func
    func makeUIView(context: Context) -> WKWebView {

        guard let url = URL(string: self.url) else {
            return WKWebView()
        }

        let request = URLRequest(url: url)
        let wkWebView = WKWebView()
        wkWebView.load(request)
        return wkWebView
    }

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

}


struct WebView_Preview: PreviewProvider {
    static var previews: some View {
        WebView(url: "https://www.google.com")
    }
}

谢谢!

最佳答案

这里有一些应该做你想做的事情。 WebView 在 Coordinator 类中有一个委托(delegate)。它改变了一个绑定(bind),ContentView 可以对此做出适当的 react 。目前它只是一个显示状态原始值的文本,但它可以替换为某种事件指示器。

struct ContentView: View {
    @State var urlString = ""
    @State var workState = WebView.WorkState.initial

    var body: some View {
        VStack(spacing: 20) {
            WebView(urlString: self.$urlString, workState: self.$workState)

            Button("Play") {
                self.urlString = "https://www.example.com/"
            }
            Text("Current work = " + self.workState.rawValue)
        }
    }
}

struct WebView: UIViewRepresentable {
    enum WorkState: String {
        case initial
        case done
        case working
        case errorOccurred
    }

    @Binding var urlString: String
    @Binding var workState: WorkState

    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.navigationDelegate = context.coordinator
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        switch self.workState {
        case .initial:
            if let url = URL(string: self.urlString) {
                uiView.load(URLRequest(url: url))
            }
        default:
            break
        }
    }

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

    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebView

        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
          self.parent.workState = .working
        }

        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            self.parent.workState = .errorOccurred
        }

        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            self.parent.workState = .done
        }

        init(_ parent: WebView) {
            self.parent = parent
        }
    }
}

关于webview - 在 SwiftUI 中加载网站时加载事件指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60348310/

相关文章:

javascript - 如何使用 setWebViewClient 在 android webview 中的 html 页面上正确打开 google play 链接?

Android Webview Javascript 注入(inject)

javascript - 如何从 webview 打开 safari 移动应用程序中的链接

SwiftUI 文本在 ForEach 内部时不会本地化

xcode - 从 Info.plist 添加的启动屏幕不适用于 iOS14.0 中的 SwiftUI 2.0

xcode11 - 为 UIKitForMac 构建,但链接到为 macOS 构建的 .tbd

android - 在 UI 中使用线程以加载网页的 Android 最佳实践?

SwiftUI Picker 不显示选项

swift - 使用 SwiftUI 预览崩溃 @Binding : communication with the app was interrupted

ios - Xcode 11.1 升级奇怪之处 - 主屏幕显示为模态视图