1.8. Grouping Compact Options with UISegmentedControl

Problem

You would like to present a few options to your users from which they can pick an option, through a UI that is compact, simple, and easy to understand.

Solution

Use the UISegmentedControl class, an example of which is shown in Figure 1-22.

A segmented control displaying four options

Figure 1-22. A segmented control displaying four options

Discussion

A segmented control is a UI component that allows you to display, in a compact UI, a series of options for the user to choose from. To show a segmented control, create an instance of UISegmentedControl. Let’s start with our view controller’s .m file:

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) UISegmentedControl *mySegmentedControl;
@end

@implementation ViewController

...

And create the segmented control in the viewDidLoad method of your view controller:

- (void)viewDidLoad{
    [super viewDidLoad];

    NSArray *segments = [[NSArray alloc] initWithObjects:
                         @"iPhone",
                         @"iPad",
                         @"iPod",
                         @"iMac", nil];

    self.mySegmentedControl = [[UISegmentedControl alloc]
                               initWithItems:segments];
    self.mySegmentedControl.center = self.view.center;
    [self.view addSubview:self.mySegmentedControl];
}

We are simply using an array of strings to provide the different options that our segmented control has to display. We initialize our segmented control using the initWithObjects: initializer and pass the array of strings and images to the segmented control. The results will look like what we saw in Figure 1-22.

Now the user can pick one of the options in the segmented control. Let’s say she has picked iPad. The segmented control will then change its user interface to show the user what option she has selected, as depicted in Figure 1-23.

User has selected one of the items in a segmented control

Figure 1-23. User has selected one of the items in a segmented control

Now the question is, how do you recognize when the user selects a new option in a segmented control? The answer is simple. Just as with a UISwitch or a UISlider, use the addTarget:action:forControlEvents: method of the segmented control to add a target to it. Provide the value of UIControlEventValueChanged for the forControlEvents parameter, because that is the event that gets fired when the user selects a new option in a segmented control:

- (void) segmentChanged:(UISegmentedControl *)paramSender{

    if ([paramSender isEqual:self.mySegmentedControl]){
        NSInteger selectedSegmentIndex = [paramSender selectedSegmentIndex];

        NSString  *selectedSegmentText =
        [paramSender titleForSegmentAtIndex:selectedSegmentIndex];

        NSLog(@"Segment %ld with %@ text is selected",
              (long)selectedSegmentIndex,
              selectedSegmentText);
    }
}

- (void)viewDidLoad{
    [super viewDidLoad];

    NSArray *segments = @[
                          @"iPhone",
                          @"iPad",
                          @"iPod",
                          @"iMac"
                          ];

    self.mySegmentedControl = [[UISegmentedControl alloc]
                               initWithItems:segments];
    self.mySegmentedControl.center = self.view.center;
    [self.view addSubview:self.mySegmentedControl];

    [self.mySegmentedControl addTarget:self
                                action:@selector(segmentChanged:)
                      forControlEvents:UIControlEventValueChanged];
}

If the user starts from the left side and selects each of the options in Figure 1-22, all the way to the right side of the control, the following text will print out to the console:

Segment 0 with iPhone text is selected
Segment 1 with iPad text is selected
Segment 2 with iPod text is selected
Segment 3 with iMac text is selected

As you can see, we used the selectedSegmentIndex method of the segmented control to find the index of the currently selected item. If no item is selected, this method returns the value –1. We also used the titleForSegmentAtIndex: method. Simply pass the index of an option in the segmented control to this method, and the segmented control will return the text for that item. Simple, isn’t it?

As you might have noticed, once the user selects an option in a segmented control, that option will get selected and will remain selected, as shown in Figure 1-23. If you want the user to be able to select an option but you would like the button for that option to bounce back to its original shape once it has been selected (just like a normal button that bounces back up once it is tapped), you need to set the momentary property of the segmented control to YES:

self.mySegmentedControl.momentary = YES;

One of the really neat features of segmented controls is that they can contain images instead of text. To do this, simply use the initWithObjects: initializer method of the UISegmentedControl class and pass the strings and images that will be used to initialize the segmented UI control:

- (void)viewDidLoad{
    [super viewDidLoad];

    NSArray *segments = @[
                          @"iPhone",
                          [UIImage imageNamed:@"iPad"],
                          @"iPod",
                          @"iMac",
                         ];

    self.mySegmentedControl = [[UISegmentedControl alloc]
                               initWithItems:segments];

    CGRect segmentedFrame = self.mySegmentedControl.frame;
    segmentedFrame.size.height = 128.0f;
    segmentedFrame.size.width = 300.0f;
    self.mySegmentedControl.frame = segmentedFrame;

    self.mySegmentedControl.center = self.view.center;

    [self.view addSubview:self.mySegmentedControl];
}

Note

In this example, the iPad file is simply an image of an iPad that’s been added to our project.

In iOS 7, Apple has deprecated the segmentedControlStyle property of the UISegmentedControl class, so segmented controls have only a single default style. We can no longer modify this style.

Get iOS 7 Programming Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.