无法添加字体为 Avenir Next Condensed [Swift 3] 的属性字符串

Unable to add attributed string with font Avenir Next Condensed [Swift 3]

    let s = NSAttributedString(string: "Percentage", attributes: [NSFontAttributeName : UIFont(name : "Avenir Next Condensed", size : 20), NSUnderlineStyleAttributeName : NSUnderlineStyle.byWord])
    textView.attributedText = s

以上代码出现以下错误: 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'-[_SwiftValue _isDefaultFace]:无法识别的选择器发送到实例 0x608000046930'

如果我将 NSFontAttributeName 更改为 UIFont.boldSystemFont(ofSize: 20),我可以看到粗体文本。 同样在添加 NSUnderlineStyleAttributeName 时,我根本看不到任何文本。 我该如何解决这个问题?

两件事:

  • 您不能将可选值传递给需要非 Null id 值的地方。

attributes: 参数在内部转换为 NSDictionary,其值不能为 nil。但是 UIFont.init(name:size:) 是一个可失败的初始化器,所以它的 return 类型是可选的。在 Swift 3.0.0 中,Swift 在将其转换为非 Null id 时生成类型 _SwiftValue 的实例。并将其存储在 attributes 中。这在 Objective-C 方面完全没用。 (即使实际值不为零,也会发生这种情况。)

(Swift 3.0.1 改善了部分情况。)

  • 您不能将 Swift 枚举传递到需要 id 值的地方。

NSUnderlineStyle.byWord 是一个 Swift 枚举。在Swift 3中,Swift在转换为id.

时会生成一个_SwiftValue类型的实例

(Swift 3.0.1 没有改善这种情况。)

要解决上面两个问题,你需要这样写:

if let font = UIFont(name: "Avenir Next Condensed", size: 20) {
    let s = NSAttributedString(string: "Percentage", attributes: [NSFontAttributeName: font, NSUnderlineStyleAttributeName: NSUnderlineStyle.byWord.rawValue])
    textView.attributedText = s
}