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.