Ulug'bek
Ulug'bek

Reputation: 2832

How to change UILabel text while a button was being pressed

I want to change text of the label to know status of progress while Touch Up action cals. Here is an example:

@IBOutlet weak var stsLabel: UILabel! // label to show to user, the progress position 

@IBAction func updateDB(_ sender: Any) {

     stsLabel.text = "creating table"
     // do some stuf

     stsLabel.text = "inserting table A"
     // some code
     // and i have some cases again

     stsLabel.text = "Complete"
 }

func setTitle(label:UILabel, title:String){
    DispatchQueue.main.async(execute: { () -> Void in
        label.text = title
    })      
}

That code will change label text, only when the action is complete. I tried with setTitle(stsLabel,"any text"), this also does not help. Please help me to solve this problem. Info: I am using 3 version of swift.

Upvotes: 1

Views: 677

Answers (1)

Giuseppe Lanza
Giuseppe Lanza

Reputation: 3699

Since you didn't provide enough info for a fully comprehensive answer, this answer is based on "best guess" and therefore it might be not accurate.

IF your "do whatever code" is executing on the main thread, then you will see UI updates just when all is done as you are blocking the main thread.

If your code looks like this:

@IBAction func updateDB(_ sender: Any) {

     stsLabel.text = "creating table"
     DispatchQueue.global().async {
         // do some stuf
     }

     stsLabel.text = "inserting table A"
     DispatchQueue.global().async {
         // some code
         // and i have some cases again
     }

     stsLabel.text = "Complete"
 }

Then the problem is that the "do some stuff" code is executed asynchronously, so all the text assignments are executed one after another on the main thread, so you will see just the last one because the other two are too fast to be seen.

If your code looks like this:

@IBAction func updateDB(_ sender: Any) {

     stsLabel.text = "creating table"
     DispatchQueue.global().async {
         // do some stuf

         stsLabel.text = "inserting table A"
         // some code
         // and i have some cases again

         stsLabel.text = "Complete"
     }
 }

Then the problem is that all UI related stuff must go on the main thread. The result of doing it off of the main thread will cause the update to occur with a huge delay, and in some cases it could result in a crash.

The healthy way to do this kind of things is by dispatching on the main thread the UI ops. The code should look like this:

@IBAction func updateDB(_ sender: Any) {

     stsLabel.text = "creating table"
     DispatchQueue.global().async {
         // do some stuf

         DispatchQueue.main.async(execute: { () -> Void in
             stsLabel.text = "inserting table A"
         }) 
         // some code
         // and i have some cases again

         DispatchQueue.main.async(execute: { () -> Void in
             stsLabel.text = "Complete"
         }) 
     }
 }

Upvotes: 1

Related Questions