Writing an app with some network activity I find myself writing the same code for multiple view controllers over and over just to display an activity indicator.
class SomeViewController: UIViewController {
let indicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
override func viewDidLoad() {
super.viewDidLoad()
// customize indicator
self.indicator.layer.cornerRadius = 10
self.indicator.center = self.view.center
self.indicator.hidesWhenStopped = true
self.indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
self.indicator.backgroundColor = UIColor(red: 1/255, green: 1/255, blue: 1/255, alpha: 0.5)
}
// MARK: - Acitivity Indicator
func startIndicatingActivity() {
DispatchQueue.main.async {
self.view.addSubview(self.indicator)
self.indicator.startAnimating()
}
}
func stopIndicatingActivity() {
DispatchQueue.main.async {
self.indicator.stopAnimating()
}
}
}
Within the same SomeViewController
class I can then use it as follows:
@IBAction func startHeavyNetworkStuffButtonPressed(_ sender: UIButton) {
startIndicatingActivity()
doHeavyNetworkStuff() { success in
// heavy networking has finished
stopIndicatingActivity()
}
}
This works fine as long as I only need to display the activity indicator in a single view controller. However, it's tedious to do it over and over for every view controller that needs this functionality. As I hate writing the same code over and over, I am in search of a solution where I can simply call
startIndicatingActivity()
(and stopIndicatingActivity()
respectively) in any view controller.
0th idea - Extension
My obvious first thought was to write an extension for the UIViewController
class. As I need to store an instance of the UIActivityIndicatorView
, however, I got the Extensions may not contain stored properties
error.
1st idea - Subclassing
Next up: subclassing UIViewController
. This would work fine for any simple view controller. However, if I needed the same functionality for a MyCustomTableViewController
, I would again need to first subclass from UITableViewController
and copy/paste existing code.
My question
Is there an elegant way to call startIndicatingActivity()
/ stopIndicatingActivity()
in any view controller while avoiding to copy/paste large amounts of code? I'm assuming an elegant solution would involve an extension
, protocol
, or some kind of multiple-inheritance approach.