Search code examples
swiftios8uibuttonibactioniboutlet

Cannot manually set the highlighted state of a UIButton in an IBAction method


Inside my ViewController, I have two IBOutlets signUpButton and memberButton, and both buttons are linked to same signUpOrMemberButtonPressed() IBAction func. I am trying to set highlighted property to these 2 buttons so I can do subsequent work accordingly inside my submitPressed() IBAction func. But I noticed odd behavior between signUpOrMemberButtonPressed() and submitPressed() IBActions. After tapping on either signUpButton or memberButton, the button was highlighted inside my signUpOrMemberButtonPressed(), but by the time it executed submitPressed(), debug showed it's not highlighted. Here is my signUpOrMemberButtonPressed():

@IBAction func signUpOrMemberButtonPressed(sender: AnyObject) {
    var button = sender as UIButton
    button.highlighted = true
    if signUpButton.highlighted {
        memberButton.highlighted = false
    } else {
        signUpButton.highlighted = false
    }

    if (signUpButton.highlighted) {
        println("signUpButton is highlighted inside 1st button")
    } else if (memberButton.highlighted) {
        println("memberButton is highlighted inside 1st button")
    } else {
        println("nothing is highlighted inside 1st button")
    }
}

My submitPressed function:

@IBAction func submitPressed(sender: AnyObject) {
    if (signUpButton.highlighted) { println("signUpButton is highlighted inside 2st button") }
    else if (memberButton.highlighted) { println("memberButton is highlighted inside 2st button") }
    else { println("nothing is highlighted inside 2nd button")
}

When run my app, I tapped on memberButton and then tapped on submit button. Here is the log output:

memberButton is highlighted inside 1st button
nothing is highlighted inside 2nd button

Nothing was set to run between these two func calls.


Solution

  • What is happening here is that the button is "un-highlighting" itself (after you manually set highlighted = true).

    From the documentation of the highlighted property:

    UIControl automatically sets and clears this state automatically when a touch enters and exits during tracking and when there is a touch up.

    You can set the highlighted state manually but you would have to do it after the UIButton unsets the highlighted state. You would have to do this on the next run loop which you can do by using dispatch_async.

    The following should work:

    var button = sender as UIButton
    dispatch_async(dispatch_get_main_queue()) {
        self.memberButton.highlighted = button == self.memberButton
        self.signUpButton.highlighted = button == self.signUpButton
    }