1

カスタム NSTextStorage サブクラスの絵文字に問題があります。このクラスは、渡された属性を保存しません。代わりに、独自のものを生成します。

override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] {
    if range != nil {
        range.memory = NSMakeRange(0, self.string.length)
    }

    let attributes = [
        NSFontAttributeName: NSFont.systemFontOfSize(14)
    ]

    return attributes
}

override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) {
    // does nothing
}

これはほとんどうまくいきます。ただし、文字列に絵文字がある場合、それらは単に表示されません。NSTextView がテキスト ストレージに対して行う呼び出しを調べると、テキスト ビューは、絵文字が表示されるたびに、絵文字範囲のフォント属性を AppleColorEmoji フォントに設定しようとするようです。「真の属性」のソースとしてテキスト ビューに依存している場合は問題ありませんが、プログラムをそのように動作させたくありません。私の場合、テキスト ストレージは、すべての属性の唯一のベンダーである必要があります。テキストビューが送信するものを属性ごとにリッスンすることはできません。

文字列内の絵文字を手動で検出し、AppleColorEmoji フォントを手動で設定する必要がありますか? それとももっと良い方法がありますか?フォールバック フォントを使用して、欠落している文字を含むフォントを自動的に検索することは既に試しましたが、それらの方法を使用しても絵文字はカバーされないようです。

4

1 に答える 1

5

理解した。つまり、属性付き文字列 (およびその結果としてテキスト ストレージ) はfixAttributesInRange(range: NSRange)、必要に応じて絵文字フォントを追加するなど、表示用の属性を整理するために、編集後に呼び出します。は、これらの追加の属性をコミットするためfixAttributesInRangeに呼び出します。setAttributes(attrs: [String : AnyObject]?, range: NSRange)これは、ローカルに構築された辞書を から販売することはできないことを意味しますattributesAtIndex(location: Int, effectiveRange range: NSRangePointer)。これらの「固定された」属性を追跡する必要があります。そうしないと、特定の状況で文字列が壊れてしまいます。

残念ながら、setAttributesはテキスト ビューからも属性を受け取りますが、これは無視したいものです。幸いなことに、これを行うことでこれを簡単に回避できます。

override func fixAttributesInRange(range: NSRange) {
    self.isFixingAttributes = true
    super.fixAttributesInRange(range)
    self.isFixingAttributes = false
}

...そして でisFixingAttributesフラグをチェックしsetAttributesます。そうすれば、「固定」属性のみがテキスト ストレージによって記録され、外部からの属性は記録されません。

于 2016-09-11T09:24:00.957 に答える