Oftentimes, you need to display an activity indicator to the user when fetching or loading data.
It’s best to keep this in one place for ease of use. Also, it’s best to make sure this is done on the main/UI thread.
Loading Screen in Swift
Here’s a way to do it in an extension that adds it to all of your UIViewControllers…
var vSpinner : UIView? extension UIViewController { func showSpinner(onView : UIView) { let spinnerView = UIView.init(frame: onView.bounds) spinnerView.backgroundColor = UIColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) let ai = UIActivityIndicatorView.init(style: .whiteLarge) ai.startAnimating() ai.center = spinnerView.center DispatchQueue.main.async { spinnerView.addSubview(ai) onView.addSubview(spinnerView) } vSpinner = spinnerView } func removeSpinner() { DispatchQueue.main.async { vSpinner?.removeFromSuperview() vSpinner = nil } } }
The vSpinner var is global so it’s a good idea to clean it up when we’re done. If you want to avoid storing it here, you can have showSpinner return it and store it… but, hey, then you’re just storing it somewhere else. AND when would you ever need two? In the code above, if you call showSpinner from another view controller, the current one will get released. 😉
To create and display the spinner, do this in your view controller:
self.showSpinner(onView: self.view)
This stores the view that’s created in vSpinner for later…
To remove it, do this:
self.removeSpinner()
The removeSpinner function makes sure it’s done on the main thread and that the spinner view is set to nil to release the memory.
Here’s how it could be used…
self.showSpinner(onView: self.view) ServerManager.login(username: username, password: password, completion: { (vals, error) in self.removeSpinner() if error != nil, vals == nil { ... } ... }
Since extensions can’t have stored properties this is one way to provide this functionality with an extension. Another way would be to create a class with static methods and a static UIView property. That’s one way I’ve done it in the past, but I wanted to do it as an extension this time.
There’s a variety of ways to solve this issue and this is one too. 🙂 Feel free to share you’re way of doing it.