UISegmentedControl tintColor

The tintColor no longer seems to apply to images or text in the UISegmentedControl (in iOS13)


Anyone know if this is by design or a bug?


Thanks

Replies

In iOS 13 the UISegmentedControl is redesigned to be a more gentle and materialized component, and I believe tintColor is no longer needed in iOS13. I would say it's by design.

I hope you're wrong. For me tinted (usually blue) image/text indicates that you can tap it.

I found that images would inherit a tint color if I had set a global tintColor at the window level. Maybe you could embed the segmented control in a container view and set the tint color on the container so that the images "inherit" the colour (that's less extreme than setting an app-wide tint at the window level as I do).


For text, you can can still use the setTitleTextAttributes:forState (that's the Obj-C name :-) ) with the normal state. It doesn't look great and you need to make sure your colour is either suitable for dark appearance, detect appearance changes and switch colours, use a dynamic colour (not tried it, but that should work), or force the segmented control into a single appearance using overrideUserInterfaceStyle.


The new style is slowly growing on me, so I probably won't fight it in my own apps. I agree they seem to lack affordance for tapping, but hopefully users will rapidly learn what they look like and that won't be an issue. Perhaps *not* looking standard will actually be a liability in the long term?

This does not work for me. I'm setting the tinitColor at the window level, but UISegmentedControl ignores it. Everywhere else seems to accept it, so I assume it's a bug.


UIApplication.shared.delegate?.window??.tintColor = theme.tintColor

iOS 13 segments ignore the tint colour for text in segments and the selected "bubble". They use the tint colour for images. The selectedSegmentTintColor can be used to change the colour of the bubble. You can also change the .normal and .selected text attributes to control the text colour.


I just answered another question that has some more info: https://forums.developer.apple.com/thread/120412


See also this Stack Overflow answer: https://stackoverflow.com/questions/56436559/how-to-change-the-colors-of-a-segment-in-a-uisegmentedcontrol-in-ios-13/56874473#56874473

I ran into this issue as well. It's related to the new dark and light modes. In light, or default, mode they auto tint button images on UISegmentedControls to black, and in light mode to white. In my case, my apps use black backgrounds on UISegmentedControl buttons so this was making my buttons invisible--and I didn't want to either change the entire UI to forced dark mode or change my color palatte just to work with Apple's automatic choices for my button colors. I tried using image xassets with light/dark options, tinting the parent view and subviews, dynamically swapping out images..none of those worked.


But I noticed that they don't do this to auto-tinting to text labels so I tried setting those attributes and it worked. It responds to the TitleTextAttributes foreground color attribute:


NSDictionary *attributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName];

[segmentedControl setTitleTextAttributes:attributes forState:UIControlStateNormal];

Thank you!!! In my case, I have UISegmentedControls in some NavigationBars and I hated how the other buttons/text where white while the UISegmentedControl was black. I just realized today that it was related to Light/Dark apperence. I ended up expanding upon your code to make a global apperance setting:

[[UISegmentedControl appearanceWhenContainedInInstancesOfClasses:@[[UINavigationBar class]]] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateNormal];