UISegmentedControl
UISegmentedControl
is a UIKit control that presents a horizontal list of segments, each acting as a button to select one option from a set of mutually exclusive choices. It is commonly used for switching between different views or modes in an iOS app. This document covers the key properties, methods, and usage of UISegmentedControl
, along with examples and best practices.
Overview of UISegmentedControl
A UISegmentedControl
is a subclass of UIControl
that allows users to select one option from a predefined set of options. Each segment can contain text, an image, or both, and the control supports customization of appearance and behavior.
Creating a UISegmentedControl
You can create a UISegmentedControl
programmatically or via Interface Builder (storyboards/xibs).
Programmatic Example:
import UIKit
let items = ["Option 1", "Option 2", "Option 3"]
let segmentedControl = UISegmentedControl(items: items)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: #selector(segmentChanged(_:)), for: .valueChanged)
view.addSubview(segmentedControl)
Key Properties of UISegmentedControl
Below are the most commonly used properties of UISegmentedControl
:
Property | Type | Description |
---|---|---|
selectedSegmentIndex | Int | The index of the currently selected segment (-1 if none). |
numberOfSegments | Int | The total number of segments (read-only). |
isEnabled | Bool | Whether the control is enabled (affects appearance and interaction). |
tintColor | UIColor | The tint color for the control (pre-iOS 13, affects segment appearance). |
selectedSegmentTintColor | UIColor? | The tint color for the selected segment (iOS 13+). |
backgroundColor | UIColor? | The background color of the control (iOS 13+). |
isMomentary | Bool | If true , the selection is not persistent (resets after interaction). |
apportionsSegmentWidthsByContent | Bool | If true , segment widths are based on content; otherwise, segments are equal width. |
Example: Configuring Properties:
segmentedControl.selectedSegmentIndex = 1
segmentedControl.backgroundColor = .systemGray6
segmentedControl.selectedSegmentTintColor = .systemBlue
segmentedControl.isEnabled = true
segmentedControl.apportionsSegmentWidthsByContent = true
Key Methods of UISegmentedControl
UISegmentedControl
inherits methods from UIControl
and UIView
, but also provides segment-specific methods:
Method | Description |
---|---|
insertSegment(withTitle:at:animated:) | Inserts a segment with a title at the specified index. |
insertSegment(with:at:animated:) | Inserts a segment with an image at the specified index. |
removeSegment(at:animated:) | Removes a segment at the specified index. |
removeAllSegments() | Removes all segments. |
setTitle(_:forSegmentAt:) | Sets the title for a segment. |
setImage(_:forSegmentAt:) | Sets the image for a segment. |
setEnabled(_:forSegmentAt:) | Enables or disables a specific segment. |
setWidth(_:forSegmentAt:) | Sets the width for a specific segment. |
titleForSegment(at:) | Returns the title for a segment. |
imageForSegment(at:) | Returns the image for a segment. |
Example: Adding and Modifying Segments:
segmentedControl.insertSegment(withTitle: "New Option", at: 2, animated: true)
segmentedControl.setImage(UIImage(systemName: "star.fill"), forSegmentAt: 0)
segmentedControl.setEnabled(false, forSegmentAt: 1)
Handling User Interaction
To respond to segment changes, add a target-action for the .valueChanged
event.
Example:
segmentedControl.addTarget(self, action: #selector(segmentChanged(_:)), for: .valueChanged)
@objc func segmentChanged(_ sender: UISegmentedControl) {
print("Selected segment index: \(sender.selectedSegmentIndex)")
}
Customizing Appearance
iOS 13 and Later
- Use
selectedSegmentTintColor
to style the selected segment. - Use
setTitleTextAttributes(_:for:)
to customize text appearance for specific states (e.g.,.normal
,.selected
). - Set
backgroundColor
for the control’s background.
Example: Customizing Text Attributes:
segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal)
segmentedControl.selectedSegmentTintColor = .systemBlue
segmentedControl.backgroundColor = .systemGray6
Pre-iOS 13
- Use
tintColor
to control the overall appearance. - Customize segment appearance with images or attributed titles.
Adding Images to Segments
Segments can display images instead of or alongside text. Use SF Symbols or custom images.
Example:
segmentedControl.setImage(UIImage(systemName: "house.fill"), forSegmentAt: 0)
segmentedControl.setImage(UIImage(systemName: "person.fill"), forSegmentAt: 1)
Best Practices
Use Clear Labels or Icons: Ensure segment titles or images are concise and intuitive.
Support Accessibility: Set accessibility labels and traits for VoiceOver.
swiftsegmentedControl.accessibilityLabel = "View selector" segmentedControl.accessibilityTraits = .button
Use Auto Layout: Set
translatesAutoresizingMaskIntoConstraints = false
and use constraints (e.g., with SnapKit).Limit Segments: Avoid overcrowding; typically, 2–5 segments are ideal for usability.
Test on Devices: Verify appearance and interaction on various screen sizes and iOS versions.
Troubleshooting
- Segment Not Responding: Ensure
isEnabled = true
and the target-action is set for.valueChanged
. - Uneven Segment Widths: Set
apportionsSegmentWidthsByContent = false
for equal widths. - Appearance Issues: Check iOS version compatibility for properties like
selectedSegmentTintColor
. - Accessibility Issues: Verify
accessibilityLabel
and test with VoiceOver.
Example: Complete UISegmentedControl Setup
import UIKit
import SnapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create segmented control
let items = ["Home", "Profile", "Settings"]
let segmentedControl = UISegmentedControl(items: items)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.backgroundColor = .systemGray6
segmentedControl.selectedSegmentTintColor = .systemBlue
segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal)
segmentedControl.addTarget(self, action: #selector(segmentChanged(_:)), for: .valueChanged)
// Accessibility
segmentedControl.accessibilityLabel = "View selector"
view.addSubview(segmentedControl)
// Auto Layout with SnapKit
segmentedControl.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
make.width.equalTo(300)
}
}
@objc func segmentChanged(_ sender: UISegmentedControl) {
let titles = ["Home", "Profile", "Settings"]
print("Selected: \(titles[sender.selectedSegmentIndex])")
}
}
Resources
- Apple UIKit Documentation: UISegmentedControl
- Apple UIControl Documentation
- SnapKit GitHub Repository (for Auto Layout)
- SF Symbols (for segment images)