One idea would be to recursively traverse through segment's view hierarchy and check if you encounter a UILabel
Set up your UISegmentControl
as normal
func addControl() {
let items = ["One", "Two", "Three"]
let segmentedControl = UISegmentedControl(items: items)
segmentedControl.frame = CGRect(x: 35, y: 200, width: 250, height: 50)
segmentedControl.center = view.center
segmentedControl.selectedSegmentIndex = 1
view.addSubview(segmentedControl)
// custom function
updateSegmentTextColor(segmentedControl)
}
This function runs through the view hierarchy and set's the color of the labels
// Just for testing
func randomColor() -> UIColor
{
let red = CGFloat(arc4random_uniform(256)) / 255.0
let blue = CGFloat(arc4random_uniform(256)) / 255.0
let green = CGFloat(arc4random_uniform(256)) / 255.0
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
private func updateSegmentTextColor(_ rootView: UIView)
{
for subview in rootView.subviews
{
if let label = subview as? UILabel
{
// Any color you want
label.textColor = randomColor()
}
updateSegmentTextColor(subview)
}
}
The result:

A couple of final notes:
- This solution could impact other tint properties you may want to set and is useful when you want to keep the same color of the text for selected and deselected states
- Future iOS updates and implementations of Segment Control could have an impact on how this works
Update
If you want to specify the title color for a specific segment, you could assume (gamble) that the segment control should lay out its subviews in the logical order.
I emphasized on assume because this order is not in our control and you are at the mercy of the implementation.
Infact, if you set the selected index segmentedControl.selectedSegmentIndex = 1
and if you have 4 segments, the order of laying out the subviews is 0, 2, 3, 1 so the selected segment gets added last.
What could work for your situation is as follows:
// Add a color queue to hold the colors for the 4 segments
var colorQueue: [UIColor] = [.red, .blue, .green, .orange]
private func updateSegmentTextColor(_ rootView: UIView)
{
for subview in rootView.subviews
{
if let label = subview as? UILabel,
!colorQueue.isEmpty
{
// Dequeue the front of the queue
let color = colorQueue.removeFirst()
label.textColor = color
}
updateSegmentTextColor(subview)
}
}
private func addControl() {
let items = ["One", "Two", "Three", "Four"]
let segmentedControl = UISegmentedControl(items: items)
segmentedControl.frame = CGRect(x: 35, y: 200, width: 250, height: 50)
segmentedControl.center = view.center
segmentedControl.tintColor = .blue
view.addSubview(segmentedControl)
// custom function
updateSegmentTextColor(segmentedControl)
// Add the selected index if you need AFTER the updates
segmentedControl.selectedSegmentIndex = 1
}
You get this
