为什么在分段控件上使用 UIControlState.normal 导致此崩溃?
Why is using UIControlState.normal on a segmented control causing this crash?
我有一个简单的 UISegmentedControl
,有两个部分,我正在尝试自定义它的外观。
我收到这个运行时错误:
*** 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)
}
由上面看到的行引起,我首先尝试设置标题文本属性(请注意,设置属性的第二行工作正常)。
根据 Apple 的文档,我应该能够使用任何有效的 UIControlState
并且 UIControlState.normal
确实看起来有效,所以我真的很困惑为什么会这样。
这条线给我带来了什么麻烦?
我看到的第一个问题是你写的很多代码在 Swift 中被重命名了 4. 不再支持属性格式 [String: Any]。你必须使用 [NSAttributedString.Key: Any].
例如:NSForegroundColorAttributeName --> NSAttributedString.Key.foregroundColor
其次,字体 AvenirNext 没有任何样式 "Demi",它只有 "DemiBold".
let titleAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
let selectedTitleAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
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]
在说这是 UIControlState
问题之前,您需要做:
sortController.setTitleTextAttributes(selectedTitleAttributes, for: UIControlState.normal)
换句话说,使用相同的工作样本(.selected
的样本)
它应该会造成同样的错误崩溃。
然后你会发现罪魁祸首是UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0))
,它returns nil。
所以字体名称无效。
您可以遍历您的字体以列出它 (see this related question) 并找到正确的字体。
是一个"usual one",所以你可以打开字体Book.app,找到它,查看它的Post脚本名称。并非 macOS 中的所有字体都在 iOS 中,但那个字体就是这种情况。
您将获得:AvenirNext-Regular、AvenirNext-Medium、AvenirNext-UltraLight, AvenirNext-Italic, AvenirNext-MediumItalic, AvenirNext-UltraLightItalic, AvenirNext -DemiBold, AvenirNext-Bold, AvenirNext-Heavy, AvenirNext-DemiBoldItalic, AvenirNext-BoldItalic, AvenirNext-HeavyItalic.
没有AvenirNext-Demi。
所以请使用您认为更适合您的需求。
如果您使用自定义字体,我建议您在 Mac 中安装它们。这样就可以很容易地查看字体的后记名称。
我有一个简单的 UISegmentedControl
,有两个部分,我正在尝试自定义它的外观。
我收到这个运行时错误:
*** 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)
}
由上面看到的行引起,我首先尝试设置标题文本属性(请注意,设置属性的第二行工作正常)。
根据 Apple 的文档,我应该能够使用任何有效的 UIControlState
并且 UIControlState.normal
确实看起来有效,所以我真的很困惑为什么会这样。
这条线给我带来了什么麻烦?
我看到的第一个问题是你写的很多代码在 Swift 中被重命名了 4. 不再支持属性格式 [String: Any]。你必须使用 [NSAttributedString.Key: Any].
例如:NSForegroundColorAttributeName --> NSAttributedString.Key.foregroundColor
其次,字体 AvenirNext 没有任何样式 "Demi",它只有 "DemiBold".
let titleAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
let selectedTitleAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
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]
在说这是 UIControlState
问题之前,您需要做:
sortController.setTitleTextAttributes(selectedTitleAttributes, for: UIControlState.normal)
换句话说,使用相同的工作样本(.selected
的样本)
它应该会造成同样的错误崩溃。
然后你会发现罪魁祸首是UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0))
,它returns nil。
所以字体名称无效。
您可以遍历您的字体以列出它 (see this related question) 并找到正确的字体。 是一个"usual one",所以你可以打开字体Book.app,找到它,查看它的Post脚本名称。并非 macOS 中的所有字体都在 iOS 中,但那个字体就是这种情况。
您将获得:AvenirNext-Regular、AvenirNext-Medium、AvenirNext-UltraLight, AvenirNext-Italic, AvenirNext-MediumItalic, AvenirNext-UltraLightItalic, AvenirNext -DemiBold, AvenirNext-Bold, AvenirNext-Heavy, AvenirNext-DemiBoldItalic, AvenirNext-BoldItalic, AvenirNext-HeavyItalic.
没有AvenirNext-Demi。
所以请使用您认为更适合您的需求。
如果您使用自定义字体,我建议您在 Mac 中安装它们。这样就可以很容易地查看字体的后记名称。