【问题标题】:Custom NSTextStorage: emoji don't show up by default自定义 NSTextStorage:表情符号默认不显示
【发布时间】:2017-01-18 17:41:34
【问题描述】:

我在自定义 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 字体?或者,还有更好的方法?我已经尝试过使用后备字体并自动搜索包含缺失字符的字体,但使用这些方法似乎无法覆盖表情符号。

【问题讨论】:

    标签: fonts emoji nstextview textkit nstextstorage


    【解决方案1】:

    想通了。简而言之,属性字符串(以及因此的文本存储)在编辑后调用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
    }
    

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

    【讨论】:

    • 你是我今天最喜欢的人。谢谢!
    • 我欠你的……快把我逼疯了。
    猜你喜欢
    • 1970-01-01
    • 2020-07-05
    • 2020-12-30
    • 1970-01-01
    • 2018-12-16
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    相关资源
    最近更新 更多