Published on

building a custom segmented control in swift

Authors
  • avatar
    Name
    James Williams
    Twitter
    About

Building a Custom Segmented Control in Swift

Segmented controls are a common UI element used to allow users to select one option from a set of choices. While UIKit provides a built-in segmented control, you might find yourself needing more customization or flexibility. This article will guide you through the process of building your own custom segmented control in Swift.

Understanding the Basics

Before diving into the code, let's understand the core components of a segmented control:

  • Segments: These are the individual buttons or labels that represent each option.
  • Selection Indicator: This visual element highlights the currently selected segment.
  • Container View: This is the main view that holds all the segments and the selection indicator.

Creating the Custom View

  1. Create a New Class: Start by creating a new Swift class that inherits from UIView. This will be the foundation of your custom segmented control.

  2. Define Properties: Declare properties to hold the following:

    • segments: An array of strings representing the options.
    • selectedSegmentIndex: An integer to track the currently selected segment.
    • segmentWidth: The width of each segment.
    • selectionIndicatorColor: The color of the selection indicator.
  3. Initialize the View: In the init(frame:) method, set up the initial layout and appearance of the segmented control. This includes:

    • Creating the container view.
    • Adding the segments as subviews.
    • Setting the initial selection indicator position.
  4. Handle Segment Selection: Implement a method to handle tap gestures on the segments. This method should:

    • Update the selectedSegmentIndex.
    • Move the selection indicator to the corresponding segment.
    • Notify any delegate or closure about the selection change.

Styling and Customization

  1. Segment Appearance: Customize the appearance of the segments by setting their background color, text color, font, and other properties.

  2. Selection Indicator: Design the selection indicator by setting its color, shape, and animation. You can use Core Graphics or other drawing techniques to create custom shapes.

  3. Layout: Adjust the layout of the segments and the selection indicator to achieve the desired look and feel. You can use Auto Layout or manual frame adjustments.

Example Implementation

import UIKit

class CustomSegmentedControl: UIView {

    // Properties
    var segments: [String] = []
    var selectedSegmentIndex = 0
    var segmentWidth: CGFloat = 100
    var selectionIndicatorColor = UIColor.blue

    // Container view
    private lazy var containerView: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        view.layer.cornerRadius = 5
        return view
    }()

    // Selection indicator
    private lazy var selectionIndicator: UIView = {
        let view = UIView()
        view.backgroundColor = selectionIndicatorColor
        view.layer.cornerRadius = 3
        return view
    }()

    // Initialize the view
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
    }

    // Setup the view
    private func setupView() {
        addSubview(containerView)
        containerView.addSubview(selectionIndicator)

        // Add segments
        for (index, segment) in segments.enumerated() {
            let segmentLabel = UILabel()
            segmentLabel.text = segment
            segmentLabel.textAlignment = .center
            segmentLabel.tag = index
            segmentLabel.isUserInteractionEnabled = true
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(segmentTapped(_:)))
            segmentLabel.addGestureRecognizer(tapGesture)
            containerView.addSubview(segmentLabel)
        }

        // Set initial selection indicator position
        updateSelectionIndicatorPosition()
    }

    // Handle segment tap
    @objc private func segmentTapped(_ sender: UITapGestureRecognizer) {
        if let segmentLabel = sender.view as? UILabel {
            selectedSegmentIndex = segmentLabel.tag
            updateSelectionIndicatorPosition()
            // Notify delegate or closure
        }
    }

    // Update selection indicator position
    private func updateSelectionIndicatorPosition() {
        let xPosition = CGFloat(selectedSegmentIndex) * segmentWidth
        selectionIndicator.frame = CGRect(x: xPosition, y: containerView.frame.height - 5, width: segmentWidth, height: 5)
    }

    // Layout subviews
    override func layoutSubviews() {
        super.layoutSubviews()
        containerView.frame = bounds
        let segmentCount = segments.count
        segmentWidth = containerView.frame.width / CGFloat(segmentCount)
        for (index, segment) in segments.enumerated() {
            if let segmentLabel = containerView.subviews[index] as? UILabel {
                segmentLabel.frame = CGRect(x: CGFloat(index) * segmentWidth, y: 0, width: segmentWidth, height: containerView.frame.height)
            }
        }
        updateSelectionIndicatorPosition()
    }
}

Using the Custom Segmented Control

  1. Instantiate the Class: Create an instance of your custom segmented control.

  2. Set Properties: Configure the properties like segments, selectedSegmentIndex, segmentWidth, and selectionIndicatorColor.

  3. Add to View Hierarchy: Add the custom segmented control to your view hierarchy.

  4. Handle Selection Changes: Implement the delegate or closure to receive notifications about segment selection changes.

Conclusion

By following these steps, you can create a custom segmented control that meets your specific design requirements and provides a more tailored user experience. Remember to experiment with different styling options and layout techniques to achieve the desired look and feel for your app.