Can I use custom values of UIControlState for my own control?

Mayosse picture Mayosse · May 18, 2010 · Viewed 9.6k times · Source

Is there a way to set a custom states -- not one of the existing UIControlState values -- for a UIControl?

In the UIControlSate enum, there are 16 bits that can be used for custom control states:

UIControlStateApplication  = 0x00FF0000,              // additional flags available for application use

The problem is that UIControl's state property is readonly.

I want to set different background images to my UIButton for custom states.

Answer

Nick Street picture Nick Street · Jan 18, 2011

You can make use of the custom states in a subclass of UIControl.

  • Create a variable called customState in which you will manage your custom states.
  • If you need to set a state, do your flag operations against this variable, and call [self stateWasUpdated].
  • Override the state property to return [super state] bitwise OR'd against your customState
  • Override the enabled, selected and highlighted setters so that they call [self stateWasUpdated]. This will allow you to respond to any changes in state, not just changes to customState
  • Implement stateWasUpdated with logic to respond to changes in state

In the header:

#define kUIControlStateCustomState (1 << 16)

@interface MyControl : UIControl {
    UIControlState customState;
}

In the implementation:

@implementation MyControl

-(void)setCustomState {
    customState |= kUIControlStateCustomState;
    [self stateWasUpdated];
}

-(void)unsetCustomState {
    customState &= ~kUIControlStateCustomState;
    [self stateWasUpdated];
}

- (UIControlState)state {
    return [super state] | customState;
}

- (void)setSelected:(BOOL)newSelected {
    [super setSelected:newSelected];
    [self stateWasUpdated];
}

- (void)setHighlighted:(BOOL)newHighlighted {
    [super setHighlighted:newHighlighted];
    [self stateWasUpdated];
}

- (void)setEnabled:(BOOL)newEnabled {
    [super setEnabled:newEnabled];
    [self stateWasUpdated];
}

- (void)stateWasUpdated {
    // Add your custom code here to respond to the change in state
}

@end