I'm trying to show a spinner during a possibly lengthy action invoked by a button press, but I can't get it to show up. Here's my code:
class ViewController: UIViewController {
var actInd : UIActivityIndicatorView!
[...]
override func viewDidLoad() {
super.viewDidLoad()
self.actInd = UIActivityIndicatorView(frame: CGRectMake(0,0, 50, 50)) as UIActivityIndicatorView
self.actInd.center = view.center
self.actInd.hidesWhenStopped = true
self.actInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
self.view.addSubview(actInd)
[...]
}
@IBAction func buttonPressed(sender: UIBarButtonItem) {
self.actInd.startAnimating()
// [...] do some work
self.actInd.stopAnimating()
}
}
It looks to me like the animation doesn't get shown when started from within the UI thread executing the button pressed (if I only start the animation in the button call without stopping, it starts to display as soon as the buttonPressed callback finishes). I tried to play around with dispatch_async
but didn't get anywhere. Here's what I tried:
First:
@IBAction func buttonPressed(sender: UIBarButtonItem) {
dispatch_async(dispatch_get_main_queue()) {
self.actInd.startAnimating()
}
shufflePlaylist()
dispatch_async(dispatch_get_main_queue()) {
self.actInd.stopAnimating()
}
}
Second:
@IBAction func buttonPressed(sender: UIBarButtonItem) {
dispatch_async(dispatch_get_main_queue()) {
shufflePlaylist()
}
}
func shufflePlaylist() {
self.actInd.startAnimating()
// [...] do the work
self.actInd.stopAnimating()
}
Third:
@IBAction func buttonPressed(sender: UIBarButtonItem) {
self.actInd.startAnimating()
dispatch_async(dispatch_get_main_queue()) {
shufflePlaylist()
}
}
func shufflePlaylist() {
// [...] do the work
self.actInd.stopAnimating()
}
I run into the same problem when trying to show the spinner after the user deletes a table view row in (which also can trigger some lengthy data update operation) in commitEditingStyle
.
So what's the right approach to show an activity indicator in those cases?