如何在 WKWebView 中添加事件指示器,它会在网页加载时显示指示器并在加载时消失?
我看过一些旧帖子,但不知道如何在 SwiftUI 中做到这一点
请参阅以下旧解决方案之一的链接
How to add Activity Indicator to WKWebView (Swift 3)
最佳答案
使用 UIViewRepresentable
创建一个 UIActivityIndicatorView :
You control when an activity indicator animates by calling the
startAnimating()
andstopAnimating()
methods. To automatically hide the activity indicator when animation stops, set thehidesWhenStopped
property to true.You can set the color of the activity indicator by using the
color
property.
struct ActivityIndicatorView: UIViewRepresentable {
@Binding var isAnimating: Bool
let style: UIActivityIndicatorView.Style
func makeUIView(context: UIViewRepresentableContext<ActivityIndicatorView>) -> UIActivityIndicatorView {
return UIActivityIndicatorView(style: style)
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicatorView>) {
isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
}
}
创建一个 LoadingView
允许您环绕您的 View :这允许您设置事件 View 内容的样式。
struct LoadingView<Content>: View where Content: View {
@Binding var isShowing: Bool
var content: () -> Content
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .center) {
self.content()
.disabled(self.isShowing)
.blur(radius: self.isShowing ? 3 : 0)
VStack {
Text("Loading...")
ActivityIndicatorView(isAnimating: .constant(true), style: .large)
}
.frame(width: geometry.size.width / 2, height: geometry.size.height / 5)
.background(Color.secondary.colorInvert())
.foregroundColor(Color.red)
.cornerRadius(20)
.opacity(self.isShowing ? 1 : 0)
}
}
}
}
如果您希望能够更新 LoadingView(...)
status 你需要引入一个从 ObservableObject
继承的 View 模型:基于此答案:https://stackoverflow.com/a/58825642/264802
class WebViewModel: ObservableObject {
@Published var url: String
@Published var isLoading: Bool = true
init (url: String) {
self.url = url
}
}
struct WebView: UIViewRepresentable {
@ObservedObject var viewModel: WebViewModel
let webView = WKWebView()
func makeCoordinator() -> Coordinator {
Coordinator(self.viewModel)
}
class Coordinator: NSObject, WKNavigationDelegate {
private var viewModel: WebViewModel
init(_ viewModel: WebViewModel) {
self.viewModel = viewModel
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.viewModel.isLoading = false
}
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<WebView>) { }
func makeUIView(context: Context) -> UIView {
self.webView.navigationDelegate = context.coordinator
if let url = URL(string: self.viewModel.url) {
self.webView.load(URLRequest(url: url))
}
return self.webView
}
}
然后在您的 View 中使用它,您将执行以下操作:struct ContentView: View {
@ObservedObject var model = WebViewModel(url: "http://www.google.com")
var body: some View {
LoadingView(isShowing: self.$model.isLoading) {
WebView(viewModel: self.model)
}
}
}
关于SwiftUI 如何在 WKWebView 中添加事件指示器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60051231/