- Published on
building a custom segmented control in swift
- Authors
- Name
- James Williams
- 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
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.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.
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.
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.
- Update the
Styling and Customization
Segment Appearance: Customize the appearance of the segments by setting their background color, text color, font, and other properties.
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.
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
Instantiate the Class: Create an instance of your custom segmented control.
Set Properties: Configure the properties like
segments
,selectedSegmentIndex
,segmentWidth
, andselectionIndicatorColor
.Add to View Hierarchy: Add the custom segmented control to your view hierarchy.
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.