I have checked other questions/answers, yet not one of them is working for me.
I have many view controllers that load the data from the database during segue preparation. Therefore, I have put the activity indicator as follows:
func tableView/collectionView (didSelectRow/item){ ...
self.showSpinner()
self.performSegue(...) -> prepare(for segue...) : data gets loaded
self.removeSpinner()
}
with functions defined in
import UIKit
var aView : UIView?
extension UIViewController{
func showSpinner(){
aView = UIView(frame: self.view.bounds)
aView?.backgroundColor = UIColor(white: 0, alpha: 0.5)
let ai = UIActivityIndicatorView(style: .large)
ai.center = aView!.center
ai.color = .red
ai.startAnimating()
aView?.addSubview(ai)
self.view.addSubview(aView!)
Timer.scheduledTimer(withTimeInterval: 20, repeats: false, block: {_ in self.removeSpinner()})
}
func removeSpinner(){
aView?.removeFromSuperview()
aView = nil
}
}
the code gets executed (I checked it), yet there is no sign of the spinner or the view with a darker background.
Even in I define
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
and put
activityIndicator.startAnimating()
performSegue...
activityIndicator.stopAnimating()
nothing happens. There are no new elements (expected: view with activity indicator or just the activity indicator) in the view hierarchy. What's wrong?
UPDATE:
if I call it in
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
self.showSpinner() //show indicator
return indexPath
all the code (willSelect, DidSelect, Segue) gets executed, and only then for 1/10 sec do I see the spinner while transitioning to the next view. I need, however, that the spinner gets shown BEFORE the further code of DidSelect gets executed
Thanks to Bear Cahill from Accelebrate! Here is the solution:
The problem was it was told to show the spinner and perform the segue. It doesn't do that until the function ends. Once the function ends it does both of those so not until it's performing the segue does the spinner show. You know it's showing b/c when you go back, it's there. So you need to call show spinner and allow control to go back to the run loop (let the function finish) and THEN call perform segue to load data, etc. I'd recommend maybe using a Timer: so you'd call showSpinner, then start a timer and in the body of the timer, call the perform segue. That way the function will end, the spinner will show and then perform segue will get called. Just have the timer set for like 0.01 seconds.