ios 如何在此WebView中添加ActivtyIndicator,以显示网站加载时?

mnowg1ta  于 2023-06-25  发布在  iOS
关注(0)|答案(2)|浏览(136)

如何添加ActivityIndicator(旋转轮)到这个WebView加载网站时?
下面是WebView的代码:

import Foundation
import SwiftUI
import WebKit

struct WebView : UIViewRepresentable {
    
    var url: String
    
    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
    }

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

下面是在另一个视图中显示WebView的代码,并告诉它要加载哪个URL:

WebView(url: "https://www.google.com")

谢谢!
编辑:我必须能够传递的URL作为一个字符串,如上图所示,当调用WebView在另一个视图。这样,我就可以很容易地告诉WebView要加载什么URL,并将WebView()的两个示例放在一个视图中,显示不同的网站,如下所示:

VStack {
WebView(url: "https://www.google.com")
WebView(url: "https://www.bing.com")
}
fv2wmkja

fv2wmkja1#

您可以使用以下代码,它包含“UIActivityIndicatorView”,并使用“WKNavigationDelegate”处理

import WebKit
import SwiftUI

struct Webview: UIViewRepresentable {
let url: URL
var activityIndicator: UIActivityIndicatorView! = UIActivityIndicatorView(frame: CGRect(x: (UIScreen.main.bounds.width / 2) - 30, y: (UIScreen.main.bounds.height / 2) - 30, width: 60, height: 60))

func makeUIView(context: Context) -> UIView {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
    let webview = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
    webview.navigationDelegate = context.coordinator
    
    let request = URLRequest(url: self.url, cachePolicy: .returnCacheDataElseLoad)
    webview.load(request)
    
    view.addSubview(webview)
    activityIndicator.backgroundColor = UIColor.gray
    activityIndicator.startAnimating()
    activityIndicator.color = UIColor.white
    activityIndicator.layer.cornerRadius = 8
    activityIndicator.clipsToBounds = true
    
    view.addSubview(activityIndicator)
    return view
}

func updateUIView(_ webview: UIView, context: UIViewRepresentableContext<Webview>) {
}

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

class WebViewHelper: NSObject, WKNavigationDelegate {

var parent: Webview
init(_ parent: Webview) {
    self.parent = parent
    super.init()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    parent.activityIndicator.isHidden = true
}

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    parent.activityIndicator.isHidden = true
    print("error: \(error)")
}

func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
    parent.activityIndicator.isHidden = true
    print("error \(error)")
}
}
lc8prwob

lc8prwob2#

Thanks to Faizan for the excellent solution!
如果您想摆脱框架逻辑(使用硬编码的数字),这里有一个使用约束的重写,以使活动指示器居中。我还将其颜色设置为.label,因此它更适合亮/暗模式。

struct WebView: UIViewRepresentable {

    let url: URL

    var activityIndicator = UIActivityIndicatorView(style: .large)

    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()

        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        activityIndicator.color = .label

        webView.addSubview(activityIndicator)
        NSLayoutConstraint.activate([
            activityIndicator.centerXAnchor.constraint(equalTo: webView.centerXAnchor),
            activityIndicator.centerYAnchor.constraint(equalTo: webView.centerYAnchor)
        ])

        webView.navigationDelegate = context.coordinator

        return webView
    }

    func updateUIView(_ webView: WKWebView, context: Context) {
        activityIndicator.startAnimating()

        let request = URLRequest(url: url)
        webView.load(request)
    }

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

}

class WebViewHelper: NSObject, WKNavigationDelegate {

    let webView: WebView

    init(_ webView: WebView) {
        self.webView = webView
        super.init()
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.webView.activityIndicator.stopAnimating()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        self.webView.activityIndicator.stopAnimating()
        print("error: \(error)")
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        self.webView.activityIndicator.stopAnimating()
        print("error: \(error)")
    }

}

相关问题