23

I have the following code snippets:

@interface Foo: UIViewController {
  ...
  UIButton *myButton;
  ...
}

@implementation Foo

- (void) viewDidLoad {
  ...
  myButton.highlighted = YES;
  ...
}

When I run the app, the button is highlighted in blue (default behavior). It works as I expected.

But after pressing the button once, the button is no longer highlighted.

Then, I created an IBAction highlightButton to handle Touch Up Inside event where I explicitly call myButton.highlighted = Yes;. Unfortunately, the button highlight still does not stay.

How can I keep it highlighted in blue even after being pressed?

Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101
pion
  • 391
  • 2
  • 4
  • 12
  • 1
    Would it be easier to just change the color of the button? :) – willcodejavaforfood Feb 18 '10 at 17:10
  • See my question [here](http://stackoverflow.com/questions/1934861/uibutton-border-and-background-image). – David Kanarek Feb 18 '10 at 17:43
  • Thanks for the tip. I am not using any image. I just use text by calling "[myButton setTitle:@"Foo" forState:UIControlStateNormal]". – pion Feb 19 '10 at 15:58
  • You should be able to do this anyway. My process was to take a screenshot of a blank, **highlighted** button, and set that as the background image for the **selected** state. Then instead of changing the **highlighted** property, I changed the **selected** property. You can set the background image in Interface Builder and never worry about it again, just turn on or off the **selected** property. – David Kanarek Feb 19 '10 at 17:21

3 Answers3

45

The solution is to do [button setHighlighted:YES] in the next runloop:

- (void)highlightButton:(UIButton *)b { 
    [b setHighlighted:YES];
}

 - (IBAction)onTouchup:(UIButton *)sender {
    [self performSelector:@selector(highlightButton:) withObject:sender afterDelay:0.0];
}
pablasso
  • 2,479
  • 2
  • 26
  • 32
Werner Altewischer
  • 10,080
  • 4
  • 53
  • 60
  • Thank you Werner. Could you possibly explain why we have to set it in the next runloop ? Does the button not get redrawn when we call this particular method ? – the_critic Dec 23 '12 at 20:15
  • 2
    Problem is the iOS framework calls onTouchup (the event handler) and afterwards unhighlights the button (setHighlighted:NO). So calling setHighlighted in the event handler doesn't have any effect. – Werner Altewischer Dec 24 '12 at 11:19
13

The simplest code is here.

dispatch_async(dispatch_get_main_queue(), ^{
    [button setHighlighted:YES];
});
mishimay
  • 4,237
  • 1
  • 27
  • 23
  • the best option. Does not make the button flash shortly to the normal state after user raises the finger. – Vilém Kurz Jun 04 '13 at 08:23
  • Not to mention that this way permits you to perform this with multiple buttons in a view and keep it VERY neat. – CaptJak Nov 10 '13 at 04:12
  • Just wondering.. the "gdc" block here is released from memory after it's done right? – lppier Dec 04 '13 at 09:14
7

An alternate way to run this is by sending a block to the main operation queue:

-(void)onTouchup:(UIButton*) button
{
    [NSOperationQueue.mainQueue addOperationWithBlock:^{ button.highlighted = YES; }];
}
Snowman
  • 31,411
  • 46
  • 180
  • 303
Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101