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 のレベルにドロップダウンし、そこで特性アプリケーションを実行することです。面倒ですが、問題は解決します。

したがって、たとえば、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 に答える