2

I'm, trying to configure segmented control bar.

The goal is to make text font of each segment in different colour. So it should look like this: example

I have read many topics, including this one: How to set UISegmentedControl Tint Color for individual segment But mainly it is discussed how to make tint colour different. And I try to make colours different in normal mode.

Sergey_VC
  • 103
  • 7

1 Answers1

2

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:

Custom Different UISegmentControl Title Text Color

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

Custom UISegmentControl Title Label Color Swift iOS UIKit

Shawn Frank
  • 4,381
  • 2
  • 19
  • 29
  • Thank you very much for your help! Yes, thats exactly what I'm trying to achieve. Can you please give a tip, how to determine a specific colour for each segment. I have tried something like this - but it says the colour is nill: if let label = segmentedControl.subviews[0] as? UILabel { label.textColor = .blue } – Sergey_VC Feb 17 '22 at 11:28
  • 1
    @Sergey_VC please see my update – Shawn Frank Feb 17 '22 at 12:12
  • yes, now its just great. Thank you so much for being generous with your time. Very clear explanation. Hope, I can be helpful to you someday too) – Sergey_VC Feb 17 '22 at 12:29
  • 1
    Happy to help and if you found this answer useful and helpful, please consider marking it as the answer. – Shawn Frank Feb 17 '22 at 12:32