Activity indicator not showing

I have a heavy code that runs for about 0.2 seconds.

I set the activity indicator as follows; however, it does not appear, but the entire screen freezes for about 0.2 seconds until the code ends.

func heavyWork() { self.actvityIndicator.startAnimating() ... // heavy loop codes here ... self.activityIndicator.stopAnimating() } 

Is this the right way to use an activity indicator?

When i comment

 // self.activityIndicator.stopAnimating() 

the activity indicator is displayed and remains there - the codes are configured correctly.

But the user interface does not seem to be updated at the right time.

As I said, the screen just freezes without showing an activity indicator until the heavy code is executed.

+6
source share
4 answers

perhaps you want to continue with this pattern:

 func heavyWork() { self.actvityIndicator.startAnimating() dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in // ... // heavy loop codes here // ... dispatch_async(dispatch_get_main_queue(), { () -> Void in self.activityIndicator.stopAnimating() }) }); } 

since the hard work should happen in the background thread, and you need to update the user interface on the main thread after.


NOTE: it is obvious that you are calling func heavyWork() on the main thread; if not, you may need to divert the original UI updates to the main thread.

+14
source

If you want the application to respond by performing some kind of heavy task, you will need to execute it in the background thread.

This is roughly what happens here: the main thread of your application runs in a launch loop. At the beginning of each iteration of the loop, iOS checks for any events (for example, user interaction, changes in view due to animation, running timers, etc.), then queues up many methods that need to be executed. Then iOS executes and executes each of these methods, and then when everything is complete, it updates the display. Then iteration of the next loop cycle begins. Updating the display is expensive, so iOS cannot do this after each line of code has been executed.

So, with your code, when you specify the ActivityInicator startAnimating function, it tells iOS that at the end of each iteration of the run loop, the activity indicator image should be updated to the next image in the animation sequence. Then, before iOS reaches the end of the current iteration of the run loop, you call stopAnimating, which tells iOS that it no longer needs to refresh images. So basically you say that he should stop before he even starts.

You can use Grand Central Dispatch to easily run code in another thread. It is important to note that any updates to the user interface must be performed in the main thread.

 func heavyWork() { self.activityIndicator.startAnimating() dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { // Do heavy work here dispatch_async(dispatch_get_main_queue()) { // UI updates must be on main thread self.activityIndicator.stopAnimating() } } } 

Also note that with asynchronous programming, for example, in the example above, you cannot return a value from the asynchronous section of the method that called it. For instance. in the above example, you cannot return the result of hard work from the heavyWork () method. This is because the function assigns the asynchronous code to run on another thread and returns immediately so that it can continue the current iteration of the run loop.

+4
source

SWIFT 4:

 func heavyWork() { self.actvityIndicator.startAnimating() DispatchQueue.global(qos: .background).async { // ... // heavy loop codes here // ... DispatchQueue.main.async { self.actvityIndicator.stopAnimating() } } } 
+2
source

This is because you are using heavy load code in the main thread. Thus, the system will never be able to complete a graphical transaction until the heavy routine ends. Your start and stop method is running simultaneously.
To avoid this, you should run the increased load method on another dispatch_queue , but note that most UIKit objects are not thread safe and should be sent again to the main queue.

+1
source

All Articles