Search code examples
swiftwkwebviewuiactivityindicatorview

UIActivityIndicator doesn't hide after loading page in WKWebView


I am trying to create a WKWebView app with a UIActivityIndicator (in Xcode 9). Below is my code, but when I try to simulate it, the activity indicator doesn't stop, neither hide.

import UIKit
import WebKit

class ViewController: UIViewController {
    @IBOutlet var loader: UIActivityIndicatorView!
    @IBOutlet var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(string: "http://www.amritvani.nl")
        let request = URLRequest(url: url!)
        webView.navigationDelegate = self as? WKNavigationDelegate
        webView.load(request)
    }

    func webViewDidStartLoad(webView: WKWebView){
        loader.startAnimating()
    }

    func webViewDidFinishLoad(webView: WKWebView){
        loader.stopAnimating()
        loader.hidesWhenStopped = true
    }
}

Could someone help me with this problem?


Solution

  • Your delegate methods are wrong. Replace webViewDidStartLoad(webView:) with this:

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        loader.startAnimating()
    }
    

    ...and webViewDidFinishLoad(webView:) with this:

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

    Also, you should conform your class to WKNavigationDelegate:

    class ViewController: UIViewController, WKNavigationDelegate
    

    There are two more problems with your code. Firstly, you shouldn't cast your class to WKNavigationDelegate with as? if it already conforms to it:

    webView.navigationDelegate = self
    

    Secondly, you should set the hidesWhenStopped attribute of your activity indicator to true before stopping it, preferably in Interface Builder or in viewDidLoad. This is not crucial, but it makes much more sense if someone else reads your code and it's also superfluous if webView(_:didFinish:) executes multiple times.