Displaying activity indicator on WKWebView using swift
Asked Answered
M

3

27

I am working on the following code and trying to show an activity indicator in the view whilst the page is loading..

I tried to implement the WKNavigationDelegate methods but I am failing as nothing shows.

Any suggestions on how to fix this?

I am not setting the SupportWebView view delegate anywhere but I wouldn't know how to do it in swift..

import UIKit
import WebKit

class SupportWebView: UIViewController, WKNavigationDelegate {
    @IBOutlet var containerView : UIView? = nil

    var webView: WKWebView?

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

    override func viewDidLoad() {
        super.viewDidLoad()

        var dataManager = DataManager.sharedDataManager()
        var url = dataManager.myValidURL
        var req = NSURLRequest(URL:url!)
        self.webView!.loadRequest(req)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }


    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }
}
Marzi answered 31/3, 2015 at 15:41 Comment(5)
This code should cause the activity indicator in the status bar to spin. There will be nothing else? Or is it not showing in the status bar either?Redpoll
there is no activity indicator showing in the status bar.. would be cool to do something similar to safari, which shows a progress bar...Marzi
You seem to be missing self.webView.navigationDelegate=self;?Redpoll
I use this HUD to show progress: github.com/jdg/MBProgressHUD. This will put up a nice big activity indicator or progress bar in the middle of the screen. If you want progress you could use a timer to keep updating it and use the self.webView.estimatedProgress from the timer to update the HUD progress.Redpoll
I added the line @Rory suggested and it works. The activity indicator spins in the upper left corner of the status bar. (iOS 8.3)Hateful
N
12

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
}
Nairn answered 13/1, 2016 at 21:23 Comment(0)
L
10

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 controller
private 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()
        }
    }
}
Labrum answered 23/3, 2018 at 13:22 Comment(2)
How to Increase the size of loader with some background image?Minnie
@Minnie spinner.transform = CGAffineTransform(scaleX: 2, y: 2)Rider
S
5

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.

Salivation answered 26/2, 2019 at 10:35 Comment(1)
For any help regarding above source code, just comment below.Salivation

© 2022 - 2024 — McMap. All rights reserved.