Fonts 自定义NSTextStorage:默认情况下不会显示表情符号

Fonts 自定义NSTextStorage:默认情况下不会显示表情符号,fonts,emoji,nstextview,textkit,nstextstorage,Fonts,Emoji,Nstextview,Textkit,Nstextstorage,我在自定义NSTextStorage子类中使用表情符号时遇到问题。该类不存储传递给它的任何属性。相反,它生成自己的: override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] { if range != nil { range.memory = NSMakeRange(0, self.string.lengt

我在自定义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字体?还是有更好的办法?我已经尝试过使用回退字体并自动搜索包含缺少字符的字体,但这些方法似乎没有涵盖表情符号。

解决了这个问题。简言之,属性化字符串和相应的文本存储在编辑后调用FixAttributesInRange:NSRange,以便整理用于表示的属性,例如,在需要时添加表情符号字体。fixAttributesInRange依次调用setAttributesattrs:[String:AnyObject]?,range:NSRange以提交这些额外的属性。这意味着您不能仅使用attributesAtIndexlocation:Int、effectiveRange range:NSRangePointer:提供本地构造的字典,您必须跟踪这些固定属性,否则在某些情况下字符串将中断

不幸的是,setAttributes还从文本视图接收属性,我们希望忽略这些属性。幸运的是,通过这样做很容易解决这个问题:

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

…然后在setAttributes中检查isFixingAttributes标志。这样,文本存储只会记录固定属性,而不会记录任何从外部传入的属性。

解决了这个问题。简言之,属性化字符串和相应的文本存储在编辑后调用FixAttributesInRange:NSRange,以便整理用于表示的属性,例如,在需要时添加表情符号字体。fixAttributesInRange依次调用setAttributesattrs:[String:AnyObject]?,range:NSRange以提交这些额外的属性。这意味着您不能仅使用attributesAtIndexlocation:Int、effectiveRange range:NSRangePointer:提供本地构造的字典,您必须跟踪这些固定属性,否则在某些情况下字符串将中断

不幸的是,setAttributes还从文本视图接收属性,我们希望忽略这些属性。幸运的是,通过这样做很容易解决这个问题:

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

…然后在setAttributes中检查isFixingAttributes标志。这样,文本存储只会记录固定属性,而不会记录任何从外部输入的属性。

你是我最喜欢的人。非常感谢。我欠你。。。快把我逼疯了。谢谢!你是我今天最喜欢的人。非常感谢。我欠你。。。快把我逼疯了。谢谢!