iosobjective-cuibutton

UIButton won't enable under some circumstances


in my application I'm using a UIButton (myButton) which I added via Storyboard.
So, when tapping the button an IBAction gets called:

-(IBAction)buttonAction:(UIButton*)sender{
    [myCustomClass doSomeCrazyStuff];
    [sender setEnabled:NO];
}

As you can see, I'm calling a method from myCustomClass ( myCustomClass is a REST-Client for my web-service).
The viewController the button lays in is delegate of myCustomClass.
There are two delegate methods implemented, one for success and one for error.

-(void)requestSucceeded{  
    /* If the request succeeded I want the button to be enabled again, and it's selected  
       state inverted */  
    NSLog(@"This gets called");
    [myButton setEnabled:YES];
    [myButton setSelected:!myButton.selected];
}

This works totally fine: I press the button, stuff is done on myCustomClass, request succeeds, button is set to inverted selected state.
But now for the other delegate method:

-(void)requestFailed{
    /* If the request failed I want the button to be enabled again, and it's selected  
       state stays the same */   
    NSLog(@"That gets called"); 
    [myButton setEnabled:YES];
}

If requestFailed gets called, the console prints That gets called as expected, but the button stays disabled... and I don't know why.
I tried other things in requestFailed like:

[myButton setHidden:YES];

Just to see if the reference to myButton is working...
And it is.

Probably I'm missing something right now, but I can't figure it out.
Thanks for your help.

EDIT:
I don't think requestFailed could be called from a different thread (as @gonji-dev mentioned), since both requestSucceeded and requestFailed are called from the same method.
In my doSomeCrazyStuff method I set up a completion block which handles connection success and error. If an error occurred it gets handled in another class. If the connection succeeded I'm asking for HTTP status codes to decide whether requestFailed or requestSucceeded will be called.


Solution

  • Similar situation as in https://stackoverflow.com/a/31952060/218152.
    Are you absolutely positive that you are invoking:

    [myButton setEnabled:YES];
    

    on the main thread?

    The industry standard, when manipulating the UI in response to notifications or multithreaded environment is:

    dispatch_async(dispatch_get_main_queue(), ^{
        // update UI
    });