didFinish делегата не вызывали в SwiftUI

#swiftui #wkwebview

Вопрос:

Я пытаюсь скрыть вид заставки, когда WKWebView загрузка закончится. Итак, в моем WebView.swift файле у меня есть координатор, содержащий делегата didFinish. Я поместил инструкцию печати в функцию делегата didFinish, но при запуске приложения я не вижу эту инструкцию печати в своей консоли отладки после завершения загрузки веб-представления. Я также пробовал использовать точки останова, и это не имеет никакого значения. Имейте в виду, что у меня также нет ошибок. Вот мое WebView.swift досье:

 import SwiftUI
import WebKit

struct SwiftUiWebView: UIViewRepresentable {
    
    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: SwiftUiWebView
        
        init(_ parent: SwiftUiWebView) {
            self.parent = parent
        }
        
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            print("Done loading")
        }
    }
    
    func makeCoordinator() -> SwiftUiWebView.Coordinator {
        Coordinator(self)
    }
    
    let url: URL?
    
    func makeUIView(context: Context) -> WKWebView {
        let prefs = WKWebpagePreferences()
        prefs.allowsContentJavaScript = true
        let config = WKWebViewConfiguration()
        config.defaultWebpagePreferences = prefs
        return WKWebView(frame: .zero, configuration: config)
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        guard let myURL = url else {
            return
        }
       
        let request = URLRequest(url: myURL)
        uiView.load(request)
    }
}
 

И SwiftUiWebview его вызывают, ContentView.swift как:

 SwiftUiWebView(url: URL(string: "www.mywebsitename.com"))
 

Кто-нибудь знает, что я здесь делаю не так?

Ответ №1:

Вам нужно установить делегат навигации на свой WKWebView , иначе он никогда не будет вызван.

Вы можете сделать это во время updateUIView вызова, обратившись к своему координатору из контекста и установив значение navigationDelegate быть context.coordinator .

 func updateUIView(_ uiView: WKWebView, context: Context) {
    guard let myURL = url else {
        return
    }

    uiView.navigationDelegate = context.coordinator // <- This sets the delegate

    let request = URLRequest(url: myURL)
    uiView.load(request)
}
 

Как только вы это сделаете, все функции navigationDelegate должны быть вызваны, если вы их реализуете.