Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

A custom checkbox subclass of UIButton

Duncan CDuncan C Posts: 9,114Tutorial Authors, Registered Users @ @ @ @ @ @ @
edited February 2013 in iPhone SDK Tutorials
I just created a demo project on github that uses a custom subclass of UIButton, WTToggleButton.

The WTToggleButton class gives a checkbox like button. Click it and it changes state to the selected state. Click it again and it changes back. It uses the UIControl "selected" property to track it's selected/not selected state.

You can download the project from github at this link WTToggleButton project on github

In order to use the new class, do the following:
  • Drag the WTToggleButton.h and .m files into your project. Select "Copy files..." and make sure they are added to your project target(s).
  • In your view controller's viewDidLoad method, add code to set the selectedImage and notSelectedImage properties of the image.
  • Connect actions to the "Value Changed" event for the button. Then, when the user clicks on the checkbox, you'll be notified.
  • Use the "selected" status of the button to see if it is in it's selected state.
Note that I provided sample graphics for the selected and not selected states, but those graphics belong to my company. You will need to create your own graphics.

The project uses ARC and storyboards. It does not use autolayout so it should work on iOS 5.0 or later.

It uses the bare minimum of internationalization code: Calling NSLocalizedString() on any string that is displayed through code. It would be a simple matter to localize this app for other languages.

Regards,
Duncan C
WareTo

widehead.gif
Animated GIF created with Face Dancer, available for free in the app store.

I'm available for one-on-one help at CodeMentor

Replies

  • Duncan CDuncan C Posts: 9,114Tutorial Authors, Registered Users @ @ @ @ @ @ @
    The code for the custom button class is actually pretty simple. It has a couple of extra properties to hold the "selected" and "not selected images:
    @interface WTToggleButton : UIButton 
    
    @property (nonatomic, retain) UIImage*	notSelectedImage;
    @property (nonatomic, retain) UIImage*	selectedImage;
    
    @end
    
    Then it has a custom setSelected method that updates the current image based on the saved state:
    - (void) setSelected: (BOOL) newValue;
    {
    	if (newValue != self.isSelected)
    	{
    		[super setSelected: newValue];
    		if (newValue)
    			[self setImage: _selectedImage forState: UIControlStateNormal];
        else
    			[self setImage: _notSelectedImage forState: UIControlStateNormal];
    	} 
    }
    

    It has a couple of custom setter methods to set the selected and not selected image properties (these methods set the image right away if needed:
    -(void) setNotSelectedImage: (UIImage*) newImage;
    {
      _notSelectedImage = newImage;
      if (!self.isSelected)
      {
        [self setImage: _notSelectedImage forState: UIControlStateNormal];
      }
    }
    
    -(void) setSelectedImage: (UIImage*) newImage;
    {
      _selectedImage = newImage;
      if (self.isSelected)
      {
        //UIButtons don't use their "selected" state, so set the non-selected state.
        [self setImage: _selectedImage forState: UIControlStateNormal];
      }
    }
    
    The real action of the custom class takes place in the UIControl method endTrackingWithTouch:

    - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
    {
    [super endTrackingWithTouch:touch withEvent:event];
    if (CGRectContainsPoint(self.bounds,[touch locationInView: self]))
    {
    self.selected = !self.selected;
    [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
    }



    If the button ends tracking touches, the code checks to see if the last touch is inside the button bounds. If so, it toggles the selected state of the button, and tells the button class to post a "value changed" event.

    To use this class, you just drag a UIButton into your interface, then change it's class to WTToggleButton.

    You need to add selected and not selected artwork to your project, and set those values in your view controller's viewDidLoad.

    Then, you can control-drag links from the custom button into your view controller's header, and attach the action to the UIControlEventValueChanged event. That's all there is to it.
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • Duncan CDuncan C Posts: 9,114Tutorial Authors, Registered Users @ @ @ @ @ @ @
    Note that I just added 2 more properties to the WTToggleButton class that let you specify the selected and not selected images as strings. The WTToggleButton will then load the images from the app bundle.

    By adding string properties, it makes a very cool trick possible:

    If you select the "WTToggleButton" object in Interface builder, you can open the identity inspector and set properties of your object using a Key Path and value. Thus, you can specify the selected and not selected image in IB instead of in code.

    The setting in the identity inspector looks like this:

    image
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
Sign In or Register to comment.