ios - SwiftUI WKWebView 检测 url 变化
问题描述
我是一个快速的学习者。我使用 SwiftUI 这是一个结构,我必须实现一个 WKWebView ,其中一个 url 是动态变化的。我必须捕捉这些不断变化的网址,但我尝试过的解决方案不起作用。
例如:https ://stackoverflow.com/a/48273950/10088243 我尝试了这个代码块,但它不起作用,它给了我一些编译器错误:
import SwiftUI
import WebKit
struct ContentView: UIViewRepresentable, WKNavigationDelegate {
let request = URLRequest(url: URL(string: "https://apple.com")!)
func makeUIView(context: Context) -> WKWebView {
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
preferences.javaScriptCanOpenWindowsAutomatically = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.allowsBackForwardNavigationGestures = true
return webView
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// 'override' can only be specified on class membe
if keyPath == #keyPath(WKWebView.url) {
print("### URL:", self.webView.url!)
}
if keyPath == #keyPath(WKWebView.estimatedProgress) {
// When page load finishes. Should work on each page reload.
if (self.webView.estimatedProgress == 1) {
print("### EP:", self.webView.estimatedProgress)
}
}
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.load(request)
}
func webViewDidFinishLoad(webView : WKWebView) {
print("Loaded: \(String(describing: webView.url))")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Loaded: \(String(describing: webView.url))")
//progressView.isHidden = true
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
//progressView.isHidden = false
print("Loaded: \(String(describing: webView.url))")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我在 struct ContentView 行有一个非类类型“ContentView”不能符合类协议“NSObjectProtocol”错误...
解决方案
您可以简单地创建一个名为“WebViewModel”的 webview 的 ObservableObject 模型类,例如
class WebViewModel: ObservableObject {
@Published var link: String
@Published var didFinishLoading: Bool = false
init (link: String) {
self.link = link
}
}
并且还进口
import WebKit
import Combine
然后复制此代码片段
struct SwiftUIWebView: UIViewRepresentable {
@ObservedObject var viewModel: WebViewModel
let webView = WKWebView()
func makeUIView(context: UIViewRepresentableContext<SwiftUIWebView>) -> WKWebView {
self.webView.navigationDelegate = context.coordinator
if let url = URL(string: viewModel.link) {
self.webView.load(URLRequest(url: url))
}
return self.webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<SwiftUIWebView>) {
return
}
class Coordinator: NSObject, WKNavigationDelegate {
private var viewModel: WebViewModel
init(_ viewModel: WebViewModel) {
self.viewModel = viewModel
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//print("WebView: navigation finished")
self.viewModel.didFinishLoading = true
}
}
func makeCoordinator() -> SwiftUIWebView.Coordinator {
Coordinator(viewModel)
}
}
struct SwiftUIWebView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIWebView(viewModel: WebViewModel(link: "https://google.com"))
//WebView(request: URLRequest(url: URL(string: "https://www.apple.com")!))
}
}
在你看来
struct AnyView: View {
@ObservedObject var model = WebViewModel(link: "https://www.wikipedia.org/")
var body: some View {
NavigationView {
SwiftUIWebView(viewModel: model)
if model.didFinishLoading {
//do your stuff
}
}
}}
因此,您可以通过这种方式获得其他代表的响应。