You might be blocking the principle thread and stopping any updates or interactions for five seconds. Display doesn’t refresh and in manufacturing your app would have been terminated by watchdog.
Strive one thing like this:
@IBAction func startButton(_ sender: Any) {
let activityIndicator = self.activityIndicator
activityIndicator.startAnimating()
DispatchQueue.predominant.asyncAfter(deadline: .now() + 0.5) {
activityIndicator.stopAnimating()
}
}
To clarify on it there are a number of methods to pores and skin this cat. However normally by no means block the principle thread with something. Both you will have costly operation or you’re ready for one thing you must do this on one other thread.
Since you’re simply passing time there isn’t a cause to make use of one other thread. You need to use a timer or dispatch queue. Timer would appear like this:
@IBAction func startButton(_ sender: Any) {
let activityIndicator = self.activityIndicator
activityIndicator.startAnimating()
Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { _ in
activityIndicator.stopAnimating()
}
}
However in the event you wished to make use of one other thread it might imply switching to a different thread, ready for five seconds (you possibly can use sleep) after which switching again to predominant thread to cease the animation. So fairly unideal to do.
I hope this provides you some extra understanding on the subject.
EDIT: From remark to switch the wait time with utilizing CoreData to do some lengthy lasting operations.
Core information has contexts. Every context represents an in-memory state of your database which is lazily loaded.
To do heavy load you need to create a brand new background context, have it carry out all your logic, save to database and report again that it’s executed.
class DatabaseManager {
let container: NSPersistentContainer
func doHeavyLoad(onDone: (() -> Void)? = nil) {
let context = container.newBackgroundContext()
context.carry out {
// Do all of the stuff right here
// Save context
strive? context.save()
// Report is completed on predominant
if let onDone {
DispatchQueue.predominant.async(execute: onDone)
}
}
}
}
This can be utilized together with your logic like so:
@IBAction func startButton(_ sender: Any) {
let activityIndicator = self.activityIndicator
activityIndicator.startAnimating()
databaseManager.doHeavyLoad {
activityIndicator.stopAnimating()
}
}
It is very important see that deliberately a context already has a carry out
technique which is able to carry out logic on the thread that context was designed to be on. It could be predominant thread or it is likely to be another thread. For that cause you will need to use DispatchQueue.predominant.async
to come back again to predominant thread in order that UI API may be known as.
Additionally word that putting sleep
inside this carry out
operation really would await given time after which exercise indicator would have been working accurately because the context just isn’t performing the sleep on the principle thread.