Arc*_*gon 1 fonts nstextview emoji nstextstorage textkit
我在自定义 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
}
Run Code Online (Sandbox Code Playgroud)
这主要工作正常。但是,如果字符串中有任何表情符号,它们就不会出现。在检查 NSTextView 对文本存储的调用时,文本视图似乎试图在任何表情符号范围出现时将其字体属性设置为 AppleColorEmoji 字体。如果您依赖文本视图作为“属性真相”的来源,那很好,但我不希望我的程序像那样工作。就我而言,文本存储需要是任何属性的唯一供应商。它无法侦听文本视图发送的任何内容,属性方面。
我是否必须手动检测字符串中的任何表情符号并手动设置 AppleColorEmoji 字体?或者,还有更好的方法?我已经尝试过使用后备字体并自动搜索包含缺失字符的字体,但是使用这些方法似乎没有涵盖表情符号。
弄清楚了。简而言之,属性字符串(以及因此的文本存储)fixAttributesInRange(range: NSRange)在编辑后调用以整理用于呈现的属性,例如在需要的地方添加表情符号字体。fixAttributesInRange,反过来,调用setAttributes(attrs: [String : AnyObject]?, range: NSRange)提交这些额外的属性。这意味着您不能只提供本地构建的字典 out of attributesAtIndex(location: Int, effectiveRange range: NSRangePointer):您必须跟踪这些“固定”属性,否则您的字符串在某些情况下会中断。
不幸的是,setAttributes还从文本视图接收属性,我们想忽略这些属性。幸运的是,通过这样做很容易解决这个问题:
override func fixAttributesInRange(range: NSRange) {
self.isFixingAttributes = true
super.fixAttributesInRange(range)
self.isFixingAttributes = false
}
Run Code Online (Sandbox Code Playgroud)
...然后检查中的isFixingAttributes标志setAttributes。这样,文本存储只会记录“固定”属性,而不会记录任何来自外部的属性。