为什么在分段控件上使用UIControlState.normal导致此崩溃?

时间:2018-10-31 13:59:46

标签: swift uisegmentedcontrol

我有一个简单的UISegmentedControl,有两个部分,我正在尝试自定义其外观。

我遇到此运行时错误:

  

***由于未捕获的异常>'NSInvalidArgumentException'而终止应用程序,原因:'-[NSNull renderingMode]:无法识别的选择器已发送到实例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确实有效,因此我对造成这种情况的原因感到非常困惑。

这行会给我带来什么麻烦?

2 个答案:

答案 0 :(得分:1)

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)),它返回nil。

因此字体名称无效。

您可以遍历您的字体以列出它(see this related question)并找到正确的字体。 这是“常规”,因此您可以打开 Font Book.app ,找到它,然后检查它的Post脚本名称。并非macOS中的所有字体都在iOS中,但是那是这种情况。

enter image description here

您将获得: 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中安装它们。这样很容易签出字体的脚本名称。

答案 1 :(得分:0)

我看到的第一个问题是您编写的许多代码已在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]