Displaying activity indicator on WKWebView using swift Displaying activity indicator on WKWebView using swift ios ios

Displaying activity indicator on WKWebView using swift


As commented, you forgot to set the webView delegate:

override func loadView() {    super.loadView()    self.webView = WKWebView()    self.webView.navigationDelegate = self    self.view = self.webView}


You should use the delegate methods for all other purposes, but key path monitoring works fine for this one purpose.

Here is a Swift 4 implementation that works fine.

// Somewhere in your view controllerprivate var loadingObservation: NSKeyValueObservation?private lazy var loadingIndicator: UIActivityIndicatorView = {    let spinner = UIActivityIndicatorView()    spinner.translatesAutoresizingMaskIntoConstraints = false    spinner.color = .black    return spinner}()override func viewDidLoad() {    super.viewDidLoad()    // Setup...    loadingObservation = webView.observe(\.isLoading, options: [.new, .old]) { [weak self] (_, change) in        guard let strongSelf = self else { return }        // this is fine        let new = change.newValue!        let old = change.oldValue!        if new && !old {            strongSelf.view.addSubview(strongSelf.loadingIndicator)            strongSelf.loadingIndicator.startAnimating()            NSLayoutConstraint.activate([strongSelf.loadingIndicator.centerXAnchor.constraint(equalTo: strongSelf.view.centerXAnchor),                                         strongSelf.loadingIndicator.centerYAnchor.constraint(equalTo: strongSelf.view.centerYAnchor)])            strongSelf.view.bringSubview(toFront: strongSelf.loadingIndicator)        }        else if !new && old {            strongSelf.loadingIndicator.stopAnimating()            strongSelf.loadingIndicator.removeFromSuperview()        }    }}


Please, below code which is working fine[Swift 4.2].

@IBOutlet weak var wv: WKWebView!@IBOutlet weak var activityIndicator: UIActivityIndicatorView!override func viewDidLoad() {    super.viewDidLoad()     loadYoutube(videoID: "KqNS7uAvOxk")     }

Now load Youtube Video

 func loadYoutube(videoID:String) {    guard let youtubeURL = URL(string: "https://www.youtube.com/embed/\(videoID)")        else { return }    wv.load( URLRequest(url: youtubeURL) )    wv.navigationDelegate = self}

Implement below this function:

 func showActivityIndicator(show: Bool) {    if show {        activityIndicator.startAnimating()    } else {        activityIndicator.stopAnimating()    }}

Implement below these three delegate method:

   func webView(_ webView: WKWebView, didFinish navigation:     WKNavigation!) {    showActivityIndicator(show: false)}   func webView(_ webView: WKWebView, didStartProvisionalNavigation    navigation: WKNavigation!) {    showActivityIndicator(show: true)}   func webView(_ webView: WKWebView, didFail navigation:    WKNavigation!, withError error: Error) {    showActivityIndicator(show: false)}

Let me know if it is not working.