Search code examples
iosobjective-ccocoa-touchuicontrol

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


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.


Solution

  • 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