URBSegmentedControl
is a more flexible alternative to the default UISegmentedControl
available in UIKit that offers easier customization and more options for layout orientations with titles and images. However, much of the same functionality and API methods that are available in UISegmentedControl
are also available in URBSegmentedControl
, making it an easier drop-in replacement within your own projects.
- Segments can be just icons or titles, or titles with icons
- Supports customizable colors and fonts
- Supports using UIAppearance for setting the global styles on all instances
- Supports blocks for value changes
- Automatically tints images based on normal and selected image colors (no need for two separate versions of your icons)
- Horizontal and vertial layout orientations for the overall control and for each individual segment
- Uses ARC and targets iOS 5.0+
CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects.
Add the following to your Podfile
and run $ pod install
:
pod "URBSegmentedControl"
If you don't have CocoaPods installed or integrated into your project, you can learn how to do via CocoaPods.
- import
URBSegmentedControl.h
andURBSegmentedControl.m
files into your project, and then include "URBSegmentedControl.h
" where needed, or in your precompiled header - link against the
QuartzCore
framework by addingQuartzCore.framework
to your project underBuild Phases
>Link Binary With Libraries
.
Once installed, you can then use URBSegmentedControl
just as you would with UIKit's UISegmentedControl
.
This project uses ARC and targets iOS 5.0+.
(see more detailed usage examples in the included project under /SampleProject)
The following is the most basic example of creating an URBSegmentedControl instance that mimics the same for UISegmentedControl:
NSArray *titles = [NSArray arrayWithObjects:[@"Item 1" uppercaseString], [@"Item 2" uppercaseString], [@"Item 3" uppercaseString], nil];
URBSegmentedControl *control = [[URBSegmentedControl alloc] initWithItems:titles];
[control addTarget:self action:@selector(handleSelection:) forControlEvents:UIControlEventValueChanged];
[viewController.view addSubview:control];
Instead of adding a target to the control to respond to value changes, you can set a handler block on each instance:
NSArray *titles = [NSArray arrayWithObjects:[@"Item 1" uppercaseString], [@"Item 2" uppercaseString], [@"Item 3" uppercaseString], nil];
URBSegmentedControl *control = [[URBSegmentedControl alloc] initWithItems:titles];
[control setControlEventBlock:^(NSInteger index, URBSegmentedControl *segmentedControl) {
NSLog(@"control value changed - index=%i", index);
}];
[viewController.view addSubview:control];
If you just want a control with icons only, you would initialize the instance with initWithIcons:
:
NSArray *icons = [NSArray arrayWithObjects:[UIImage imageNamed:@"mountains.png"], [UIImage imageNamed:@"snowboarder.png"], [UIImage imageNamed:@"biker.png"], nil];
URBSegmentedControl *control = [[URBSegmentedControl alloc] initWithIcons:icons];
[viewController.view addSubview:control];
Alternative, you can initialize an instance with both titles and images (as long as both arrays provided for each are equal in length):
NSArray *titles = [NSArray arrayWithObjects:[@"Item 1" uppercaseString], [@"Item 2" uppercaseString], [@"Item 3" uppercaseString], nil];
NSArray *icons = [NSArray arrayWithObjects:[UIImage imageNamed:@"mountains.png"], [UIImage imageNamed:@"snowboarder.png"], [UIImage imageNamed:@"biker.png"], nil];
URBSegmentedControl *control = [[URBSegmentedControl alloc] initWithTitles:titles icons:icons];
[viewController.view addSubview:control];
Your URBSegmentedControl
can be customized using the following properties:
// base styles
@property (nonatomic, strong) UIColor *baseColor; // default [UIColor colorWithWhite:0.3 alpha:1.0]
@property (nonatomic, strong) UIColor *strokeColor; // default [UIColor darkGrayColor]
@property (nonatomic, assign) CGFloat strokeWidth; // default 2.0
@property (nonatomic) CGFloat cornerRadius; // default 2.0
@property (nonatomic, assign) UIEdgeInsets segmentEdgeInsets; // default UIEdgeInsetsMake(4.0, 4.0, 4.0, 4.0)
@property (nonatomic, assign) URBSegmentImagePosition imagePosition; // default URBSegmentImagePositionLeft
// segment styles
@property (nonatomic, strong) UIColor *segmentBackgroundColor; // default [UIColor redColor]
@property (nonatomic, strong) UIColor *imageColor; // default [UIColor grayColor]
@property (nonatomic, strong) UIColor *selectedImageColor; // default [UIColor whiteColor]
@property (nonatomic, assign) BOOL showsGradient; // determines if the base and segment background should have a gradient applied, default YES
By default, your images will be tinted with the colors you define using the imageColor
and selectedImageColor
properties. If you would rather keep your images in their original format, just set these color properties to nil
:
control.imageColor = nil;
control.selectedImageColor = nil;
In most cases, the default insets applied to the content, title and image for each segment will work. However, if your control is smaller or you wish to adjust the sizes of elements better, you can adjust the insets by setting the following properties on your instance:
@property (nonatomic, assign) UIEdgeInsets contentEdgeInsets;
@property (nonatomic, assign) UIEdgeInsets titleEdgeInsets;
@property (nonatomic, assign) UIEdgeInsets imageEdgeInsets;
- Support setting images to use for background and segment states instead of drawing in CoreGraphics within the class
- Support for UISegmentedControl's
momentary
mode- Better support for customization using UIAppearance
The sample URBSegmentedControlDemo project uses the following icons from their respective authors (all from The Noun Project ):
- Snowboarder designed by Vlad Likh from The Noun Project (under public domain)
- Mountains designed by Chris Cole from The Noun Project
- Bike Hop designed by Alfonso Melolonta Urbán from The Noun Project
This code is distributed under the terms and conditions of the MIT license. Review the full LICENSE for all the details.
Think you found a bug or just have a feature request? Just post it as an issue, but make sure to review the existing issues first to avoid duplicates. You can also hit me up at @u10int for anything else, or to let me know how you're using this component. Thanks!