noblerare
noblerare

Reputation: 11863

How do I display an Activity Indicator Alert Controller while running a time-consuming function?

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

Answers (1)

Duncan C
Duncan C

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

Related Questions