Reputation: 11863
I have Xcode 8.2, iOS 10, Swift 3.
In my app, the user clicks a button "Start Processing" which kicks off a time-consuming function. I want there to be an Alert window that contains an Activity Indicator. However, all of the tutorials I see just show me how to start and stop it instead of how to pair it asynchronously with running of a function.
My code is something like this:
func doProcessing() {
for (...) {
timeConsumingFunction()
}
}
// This function displays a setup which allows the user to manually kick off the time consuming processing.
func displaySetupScreen() {
let alertController = UIAlertController(title: "Settings", message: "Please enter some settings.", preferredStyle: .alert)
// ask for certain settings, blah blah.
let actionProcess = UIAlertAction(title: "Process", style: .default) { (action:UIAlertAction) in
//This is called when the user presses the "Process" button.
let textUser = alertController.textFields![0] as UITextField;
self.doProcessing()
// once this function kicks off, I'd like there to be an activity indicator popup which disappears once the function is done running.
}
self.present(alertController, animated: true, completion: nil)
}
// this displays the actual activity indicator ... but doesn't work
func displayActivityIndicator() {
// show the alert window box
let alertController = UIAlertController(title: "Processing", message: "Please wait while the photos are being processed.", preferredStyle: .alert)
let activityIndicator : UIActivityIndicatorView = UIActivityIndicatorView()
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
activityIndicator.startAnimating()
self.present(alertController, animated: true, completion: nil)
}
Basically, I don't know how to start and stop the activity indicator at the right times and how I can display an alert controller during that time.
Thank you for your help.
Upvotes: 0
Views: 1898
Reputation: 131408
As the link ebby94 posted in his comment says, you should really avoid running a time-consuming task on the main thread. It freezes the UI, and the system Springboard will eventually terminate your app as hung if you take too long.
You should really run your long-running task on a background task. I can't really explain that in any detail without more information.
If you are determined to run your time-consuming task on the main thread then you need to start the activity indicator spinning, then return and give the event loop time to actually start the animation before your task begins. Something like this:
activityIndicator.startAnimating()
DispatchQueue.main.async {
//Put your long-running code here
activityIndicator.stopAnimating()
}
The code inside Dispatch will still be run on the main thread, but first the run loop will get a chance to start the activity indicator.
Upvotes: 2