Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 960
Mayosse Avatar asked May 18 '10 09:05

Mayosse


People also ask

What is UIControlState?

UIControlState() is an "empty" control state with some undocumented default value. It just so happens that both of these are backed with a raw value of 0 . So it seems that both represent the "normal" state. But it is bad practice to rely on this. The defaults could change.

What is control state in IOS?

Overview. A control can have more than one state at a time. Controls can be configured differently based on their state. For example, a UIButton object can be configured to display one image when it is in its normal state and a different image when it is highlighted.


2 Answers

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 
like image 94
Nick Street Avatar answered Oct 13 '22 14:10

Nick Street


Based on @Nick answer I have implemented a simpler version. This subclass exposes a BOOL outlined property that is similar in function to selected, highlighted and enabled.

Doing things like [customButtton setImage:[UIImage imageNamed:@"MyOutlinedButton.png"] forState:UIControlStateOutlined] makes it automagically work when you update the outlined property.

More of these state + property could be added if needed.


UICustomButton.h

extern const UIControlState UIControlStateOutlined;  @interface UICustomButton : UIButton @property (nonatomic) BOOL outlined; @end 

UICustomButton.m

const UIControlState UIControlStateOutlined = (1 << 16);  @interface OEButton () @property UIControlState customState; @end  @implementation OEButton  - (void)setOutlined:(BOOL)outlined {     if (outlined)     {         self.customState |= UIControlStateOutlined;     }     else     {         self.customState &= ~UIControlStateOutlined;     }     [self stateWasUpdated]; }  - (BOOL)outlined {     return ( self.customState & UIControlStateOutlined ) == UIControlStateOutlined; }  - (UIControlState)state {     return [super state] | self.customState; }  - (void)stateWasUpdated {     [self setNeedsLayout]; }  // These are only needed if you have additional code on -(void)stateWasUpdated // - (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]; // }  @end 
like image 45
Ricardo Sanchez-Saez Avatar answered Oct 13 '22 14:10

Ricardo Sanchez-Saez