1

Why doesn't this work?

dispatch_async(dispatch_get_main_queue(), {
    self.timeStringLabel.text = "\(self.timeStringSelected)"

    println(self.timeStringLabel.text)
})

I'm trying to update a label in Swift but the UI for the label never changes. I keep googling it, but I can't find any responses that don't use dispatch_async. What am I doing wrong?

1st Edit: I was mistaken. I'm not printing the updated text. The text never changes. It always prints out Optional("0") if that helps. The default value is 0 as defined in the Storyboard.

I have tried it with and without dispatch_async without any success. I also tried adding self.timeStringLabel.setNeedsDisplay() Immediately after updating the text, but that also doesn't work.

Edit 2: Here's the complete function + UILabel declaration

@IBOutlet weak var timeNumberLabel: UILabel!

@IBAction func timeNumberButtonPressed(sender: UIButton) {

    println("Number Selected. Tag \(sender.tag)")

    dispatch_async(dispatch_get_main_queue()) {

        self.timeNumberOneButton.selected = false
        self.timeNumberTwoButton.selected = false
        self.timeNumberThreeButton.selected = false
        self.timeNumberFourButton.selected = false

        if sender.tag == 0{
            self.timeNumberSelected = 0
        } else if sender.tag == 1 {
            self.timeNumberSelected == 5
        } else if sender.tag == 2 {
            self.timeNumberSelected == 10
        } else {
            self.timeNumberSelected == 24
        }

        sender.selected = true

        self.timeNumberLabel.text = "\(self.timeNumberSelected)"

        self.timeNumberLabel.setNeedsDisplay()


        println(self.timeNumberLabel.text)
    }
}

The label is clearly visible as shown in this picture. I didn't think it would be this hard to implement, but I was very wrong. I'm willing to bet it's something really simple that I'm missing.

enter image description here

josealvarado111
  • 565
  • 1
  • 9
  • 24

1 Answers1

1

Try adding the line

self.timeStringLabel.setNeedsDisplay()

(after the label change)

Because the code is run asynchronously, the interface-updating methods may miss the change and not display it (especially if a time-consuming bit of code occurs before the label change). Adding this code forces the interface to check for and display any changes it may have missed.

This should be used after any asynchronous task that changes the interface, as the task's running may overlap with the interface methods, resulting in a missed change.

*Thanks to the iOS Development Journal

mginn
  • 16,036
  • 4
  • 26
  • 54
  • 2
    Why do we need to call your line of code? Would be appreciated to learn something from here if you include more information. I mean what scenario do we need to call `setNeedsDisplay()`? I normally will do something like what OP does. – Lucas Huang Jun 01 '15 at 02:33
  • That's weird that it does not seem to have long process before updating. So, let me describe it. You need to include `setNeedsDisplay()` because it's async call that main thread might miss to update it because normally main thread runs synchronously? And system will handle that for you when you include that method? – Lucas Huang Jun 01 '15 at 04:44