2016-09-10 134 views
1

我在自定义NSTextStorage子类中遇到表情符问题。该类不存储传递给它的任何属性。相反,它产生自己的:自定义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字体?或者,还有更好的方法?我已经尝试过使用后备字体并自动搜索包含缺少字符的字体,但表情符号似乎并未使用这些方法进行覆盖。

回答

2

找出来了。简而言之,在编辑之后,归属字符串(以及随后的文本存储器)调用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 
} 

...然后在setAttributesisFixingAttributes标记检查。这样,只有“固定”属性将被文本存储器记录,而不是从外部进入的任何属性。