Can't programmatically hide UIButton created with IB

16,444

Solution 1

Ok I found a workaround that works but I still don't know why my original code wasn't working in the first place. I used Grand Central Dispatch to dispatch a block containing the hide call on the main queue, like this:

dispatch_async(dispatch_get_main_queue(), ^{
    self.myButton.hidden = YES; //works
});

Interesting. None of the initial code in my IBOutlet was wrapped in GCD blocks though. Any ideas?

Solution 2

That should work, try rename it and hide it just to check that there aren't two buttons on top of each other.

Solution 3

I had this same problem and found the solution was to put the hidden in the right place, in my case in the viewDidLoad function.

Solution 4

User Interface (UI) API (UIKit ...) methods have to be run on Main Thread!

So this will run on Main thread (as *dispatch_get_main_queue*):

dispatch_async(dispatch_get_main_queue(), ^{
    self.myButton.hidden = YES; //works
});

BUT usually we do something like this:

[self performSelectorOnMainThread:@selector(showButton) withObject:nil waitUntilDone:NO];

[self performSelectorOnMainThread:@selector(hideButton) withObject:nil waitUntilDone:NO];

-(void)showButton
{
    myButton.hidden = NO;
}

-(void)hideButton
{
    myButton.hidden = YES;
}

As per Apple's documentation: http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html " Threading Considerations Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread. "

Share:
16,444
DavidD
Author by

DavidD

Updated on June 03, 2022

Comments

  • DavidD
    DavidD almost 2 years

    My iOS UIButton is correctly linked from IB to an IBOutlet in my view controller, as I can change its title from my code. Ie:

    [self.myButton setTitle:@"new title" forState:UIControlStateNormal]; //works
    

    However,

    [self.myButton setHidden:YES]; //doesn't work
    //or
    self.myButton.hidden = YES; //doesn't work
    

    What's going on? How can I make myButton disappear?

    Update: some additional info

    Here's the code related in to my UIButton:

    in my .h file

    IBOutlet UIButton *myButton;
    -(IBAction)pushedMyButton:(id)sender;
    @property (nonatomic,retain) UIButton *myButton;
    

    in my .m file

    @synthesize myButton;
    - (void)pushedMyButton:(id)sender{
        self.myButton.hidden = YES;
    }
    - (void)dealloc{
        [self.myButton release];
    }
    
  • makdad
    makdad over 13 years
    I had a similar problem recently. This may not be a "bug" in the Apple sense, but rather a changed behavior that we're not aware of. What version of the SDK are you running?
  • makdad
    makdad over 13 years
    I have the same - I just compiled a sample project and... it works. So it's not a bug..?
  • Nico Huysamen
    Nico Huysamen about 12 years
    Jip, just did that too. Wanted to post it then saw you did :)
  • KPK
    KPK over 11 years
    Same here with the XCode 4.3.3... The thing is that all other buttons work fine, just this button I added doesn't. The only difference might be that this one does not have a texture but I simply put in some text...
  • momo
    momo over 4 years
    That's because all the iOS UIkit SDK methods (ViewDidLoad...) runs on Main thread!
  • momo
    momo over 4 years
    That's because all the iOS UIkit SDK methods (ViewDidLoad...) runs on Main thread!