3

我正在尝试创建一个 Swift 自定义文本编辑器(精简版)并陷入 iOS 8 fontDescriptorWithSymbolicTraits 错误,返回 nil。是否有任何 Swift 解决方法?

我在这里创建了一个小项目示例,您可以下载并运行以下场景:

  1. 选择一个文本
  2. 点击“ B ”按钮
  3. 点击“”按钮

应用程序崩溃,fontDescriptorWithSymbolicTraits返回nil:(

private func addOrRemoveTraitWithName(traitName: String, traitValue: UInt32) {
    let range = self.textEditor.selectedRange
    let currentAttributesDict = self.textEditor.textStorage.attributesAtIndex(range.location, effectiveRange: nil)
    let currentFont = currentAttributesDict[NSFontAttributeName]

    let fontDescriptor = currentFont?.fontDescriptor()
    let fontNameAttribute = fontDescriptor?.fontAttributes()[UIFontDescriptorNameAttribute]

    var changedFontDescriptor: UIFontDescriptor?

    if fontNameAttribute?.rangeOfString(traitName).location == NSNotFound {
      let existingTraitsWithNewTrait = UIFontDescriptorSymbolicTraits(rawValue: fontDescriptor!.symbolicTraits.rawValue | traitValue)
      changedFontDescriptor = fontDescriptor?.fontDescriptorWithSymbolicTraits(existingTraitsWithNewTrait)
    } else {

      let existingTraitsWithoutTrait = UIFontDescriptorSymbolicTraits(rawValue: fontDescriptor!.symbolicTraits.rawValue & ~traitValue)
      changedFontDescriptor = fontDescriptor?.fontDescriptorWithSymbolicTraits(existingTraitsWithoutTrait)

    }

    let updatedFont = UIFont(descriptor: changedFontDescriptor!, size: 0.0)

    var dict = [String : AnyObject]()
    dict[NSFontAttributeName] = updatedFont
    self.textEditor.textStorage.beginEditing()
    self.textEditor.textStorage.setAttributes(dict, range: range)
    self.textEditor.textStorage.endEditing()
}

我强烈建议快速查看示例项目

我有什么选择?

我还看到,在 Apple 文档中,SDK 和文档中缺少其他人使用的方法

其他人对此有何评论:

  1. 字体描述符在 iOS 8 中返回 nil
  2. http://www.openradar.me/19922049
4

1 回答 1

3

你是对的。幸运的是,该错误已在 iOS 8.3 中修复。唯一可靠的解决方法是下降到 Core Text 的级别并在那里执行 trait 应用程序。这很痛苦,但它解决了问题。

因此,例如,在 iOS 8.3 之前,这不起作用:

if let body = UIFont(name: "GillSans", size: 15),
    emphasis = body.fontDescriptor().fontDescriptorWithSymbolicTraits(.TraitItalic) {
        fbody = body
        femphasis = UIFont(descriptor: emphasis, size: 0)
}

所以你必须import CoreText下降到那个级别:

if let body = UIFont(name: "GillSans", size: 15),
    result = CTFontCreateCopyWithSymbolicTraits(body as CTFont, 0, nil, .ItalicTrait, .ItalicTrait) {
        fbody = body
        femphasis = result as UIFont
}

幸运的是,Swift 1.2 及更高版本意识到 UIFont 和 CTFont 现在是免费桥接的。在 Swift 1.2 之前,这更加复杂!当然,在早期的系统中,它们不是免费桥接的,这更加困难。

于 2016-03-19T00:51:23.543 回答