Skip to content

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:

swift
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:

PropertyTypeDescription
selectedSegmentIndexIntThe index of the currently selected segment (-1 if none).
numberOfSegmentsIntThe total number of segments (read-only).
isEnabledBoolWhether the control is enabled (affects appearance and interaction).
tintColorUIColorThe tint color for the control (pre-iOS 13, affects segment appearance).
selectedSegmentTintColorUIColor?The tint color for the selected segment (iOS 13+).
backgroundColorUIColor?The background color of the control (iOS 13+).
isMomentaryBoolIf true, the selection is not persistent (resets after interaction).
apportionsSegmentWidthsByContentBoolIf true, segment widths are based on content; otherwise, segments are equal width.

Example: Configuring Properties:

swift
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:

MethodDescription
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:

swift
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:

swift
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:

swift
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:

swift
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.

    swift
    segmentedControl.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

swift
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

Released under the MIT License.