iPhone iOS 4 UIButton toggle highlighted state on and off

I got a UIButton with style "Info Dark" set up in interface builder in my iPhone 4 app. One of the properties of the button is "Highlighted", which displays a white highlight around the button.

I would like to toggle this white highlight on and off, indicating if the button function is active or not.

The button is linked for "Touch up inside" event in the interface builder with this callback:

infoButton.highlighted = !infoButton.highlighted;

After the first touch, the highlight disappears and does not toggle as I expect it to. What else do I need to do to make the highlight toggle and display the state of the button?

Thank you!

Update: When loaded from the interface builder, the button stays highlighted, even as the view appears/disappears. What causes this to happen is the "shows touch on highlight" interface builder property. If I assign the code above to another button, the info button highlights on and off as expected. However, the touches of the info button itself interfere with the above code, causing the button to lose the "touch" highlight

Update 2: I added another info button, directly below the first info button, in the interface builder and made it glow permanently. To create the appearance of the toggle, I hide and unhide the glowInfoButton below the real one. This works as expected:

    infoButton.highlighted = NO;
    glowInfoButton.highlighted = YES;
    glowInfoButton.enabled = NO;
    glowInfoButton.hidden = YES;

- (IBAction)toggleInfoMode:(id)sender {
//    infoButton.selected = !infoButton.selected;
    glowInfoButton.hidden = !glowInfoButton.hidden;
 }

Answers


Now that I see what you really were after I would advise subclass UIButton and check for a call to an event then toggle highlight state accordingly. You can do this without adding the dummy button.

in a custom button class implementation file place the following code, or similar:

#import "HighlightedButton.h"

@implementation HighlightedButton

BOOL currentHighlightState;

-(void)toggleHighlight:(id)sender {
  self.highlighted = currentHighlightState;
}

-(void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
  //get the string indicating the action called
  NSString *actionString = NSStringFromSelector(action);
  //get the string for the action that you want to check for
  NSString *touchUpInsideMethodName = [[self actionsForTarget:target forControlEvent:UIControlEventTouchUpInside] lastObject];

  if ([touchUpInsideMethodName isEqualToString:actionString]){
    //toggle variable
    currentHighlightState = !currentHighlightState;
    //allow the call to pass through
    [super sendAction:action to:target forEvent:event];
    //toggle the property after a delay (to make sure the event has processed)
    [self performSelector:@selector(toggleHighlight:) withObject:nil afterDelay:.2];
  } else {
    //not an event we are interested in, allow it pass through with no additional action
    [super sendAction:action to:target forEvent:event];
  }

}

@end

That was a quick run at a proper solution, there is a flicker on toggle that you may not like. I am sure if you play around with some changes that can be corrected. I tried it and actually like it for your stated case.


The Highlighted image is what displays when the UIButton is being pressed, and is controlled within the UIButton itself.

You're looking for the Selected property. You can set a Selected Image in IB, and then put a infoButton.selected = !infoButton.isSelected; in your TouchUpInside callback.


The highlighted property doesn't work like that, buttons aren't toggles.

It's just to know if the button is being pressed, if I'm correct.

If you want to implement that functionality, I recommend you subclass UIButton or UIControl.


The highlighted state of a UIButton is simply setting the button's alpha to 0.5f. So if you set the button to not change on highlight, then just toggle the alpha between 0.1 and 0.5.

For example:

- (void)buttonPressed:(id)sender {

    if((((UIButton*)sender).alpha) != 1.0f){

        [((UIButton*)sender) setAlpha:1.0f];
    } else {
        [((UIButton*)sender) setAlpha:0.5f];
    }

}

Perhaps what you really want is

infoButton.enabled = NO;

This will dim the button and disable touches when set to no, allow normal operation when set to YES.

or in your case:

infoButton.enabled = !infoButton.isEnabled;

to toggle the availability of same.

If you put this in your touchupinside event, of course it will work only the first time. After that is disabled and does not receive touch events. You would put it in another method that decides whether or not the button should be enabled.

If you truly want it to change each time it is pressed then you probably should use a switch or you may look at the -imageForState, -setTitle:forState and/or -setTitleColor:forState methods. If you want to toggle the appearance each time it is touched, you could change these.


Need Your Help

Uploading picture after migration from IIS 6.0 to IIS 7.5

asp-classic migration iis-6 iis-7.5

We've got a problem when trying to upload a picture to a IIS application after we've migrated from Windows Server 2003 & IIS 6.0 to Windows Server 2008 R2 & IIS 7.5 a couple of days ago.

Picking an image from the new Photos application

android android-intent

I am using the following Intent to allow the user to choose a picture