I have a simple UISegmentedControl
with two segments and I'm trying to customize its appearance.
I'm getting this runtime error:
*** Terminating app due to uncaught exception >'NSInvalidArgumentException', reason: '-[NSNull renderingMode]: unrecognized selector sent to instance 0x112156f08'
@IBOutlet weak var sortController: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
styleSortController()
// other setup code
}
func styleSortController() {
let titleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white, NSFontAttributeName: UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0)) as Any]
let selectedTitleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white,
NSFontAttributeName: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
// this line causes it to crash
sortController.setTitleTextAttributes(titleAttributes, for: UIControlState.normal)
// but this line works, no problem
sortController.setTitleTextAttributes(selectedTitleAttributes, for: UIControlState.selected)
}
caused by the line seen above where I first try to set a title text attribute (note that the second line setting an attribute works just fine).
According to Apple's documentation, I should be able to use any valid UIControlState
and UIControlState.normal
sure seems valid so I'm really confused about why this is happening.
What could this line be causing me trouble?
let titleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white,
NSFontAttributeName: UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0)) as Any]
let selectedTitleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white,
NSFontAttributeName: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
Before saying it's the UIControlState
issue, you need to do:
sortController.setTitleTextAttributes(selectedTitleAttributes, for: UIControlState.normal)
In other words, use the same working sample (the one for .selected
)
It should create the same error crash.
Then you'll find that the culprit is UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0))
, it returns nil.
So the font name is not a valid one.
You can iterate through your Font to list it (see this related question) and find the correct one. It's a "usual one", so you can open Font Book.app, find it, and check the Post script name of it. Not all font in macOS are in iOS, but that's the case for that one.
You'll get: AvenirNext-Regular, AvenirNext-Medium, AvenirNext-UltraLight, AvenirNext-Italic, AvenirNext-MediumItalic, AvenirNext-UltraLightItalic, AvenirNext-DemiBold, AvenirNext-Bold, AvenirNext-Heavy, AvenirNext-DemiBoldItalic, AvenirNext-BoldItalic, AvenirNext-HeavyItalic.
There is no AvenirNext-Demi.
So use the one you think fit more your need.
I recommend if you use custom font to install them in your Mac. It's easy to checkout the postscript name of the font that way.