我在自定义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字体?或者,还有更好的方法?我已经尝试过使用后备字体并自动搜索包含缺失字符的字体,但似乎没有使用这些方法覆盖表情符号。
答案 0 :(得分:3)
想出来。简而言之,归因字符串(以及因此文本存储)在编辑之后调用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
标记。这样,文本存储只会记录“固定”属性,而不会从外部记录任何属性。