gpt4 book ai didi

ios - NSTextStorage 子类在某些情况下无法处理表情符号字符和更改字体

转载 作者:搜寻专家 更新时间:2023-10-30 22:00:12 40 4
gpt4 key购买 nike

我正在子类化 NSTextStorage 来做一些链接突出显示,我已经阅读了 I can on the topic .一切正常,直到我输入 🏒 表情符号字符。

我的子类:

private let ims = NSMutableAttributedString()

override var string: String {
return ims.string
}

override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] {
return ims.attributesAtIndex(location, effectiveRange: range)
}

override func replaceCharactersInRange(range: NSRange, withString str: String) {
ims.replaceCharactersInRange(range, withString: str)
self.edited(.EditedCharacters, range: range, changeInLength:(str as NSString).length - range.length)
}

override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) {
ims.setAttributes(attrs, range: range)
self.edited(.EditedAttributes, range: range, changeInLength: 0)
}

没什么复杂的。然后,当输入臭名昭著的角色时,它会出于某种随机原因切换到 Courier New:

Anything but Courier New!

现在我选择 🏒 字符,还有其他导致这种疯狂的字符。我在键入时查询了字体,它来自“系统”>“Apple Emoji”>“Courier New”。

我还尝试在 processEditing() 中设置字体,这半解决了问题,它会导致添加额外的空间(虽然不是在模拟器中)。我正在硬编码一个值 == 坏。

终极问题:

我做错了什么?我在其他人的实现中没有看到这个问题,我确定开发人员已经将 NSTextStorage 子类化。

注意:我可以在 objc.io's demo app 中确认存在同样的问题。

最佳答案

这是我外行的理解。大多数表情符号仅存在于 Apple 的 AppleColorEmoji 字体中。当您键入表情符号字符时,您的 NSTextStorage 调用 processEditing,然后调用 fixAttributesInRange。此方法可确保将字符串中任何缺失的字符替换为支持它们的字体。如果您的字符串包含表情符号,则所有包含表情符号的范围都将获得 AppleColorEmoji 字体属性。

不幸的是,没有什么能阻止这个新的字体属性“感染”在它之后键入的字符。 AppleColorEmoji 似乎不包含通常的 ASCII 集,因此这些后续字符会“固定”为等宽字体。

该怎么办?在我的程序中,我想手动管理我的文本存储的属性,因为我不希望复制和粘贴的文本为我的文本添加新的样式。这意味着我可以简单地这样做:

override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) {
if self.isFixingAttributes {
self.attributedString.setAttributes(attrs, range: range)
self.edited(NSTextStorageEditActions.EditedAttributes, range: range, changeInLength: 0)
}
}

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

override func processEditing() {
// not really fixing -- just need to make sure setAttributes follows orders
self.isFixingAttributes = true
self.setAttributes(nil, range: self.editedRange)
self.setAttributes(self.dynamicType.defaultAttributes(), range: self.editedRange)
self.isFixingAttributes = false

super.processEditing()
}

每当键入新文本时,我只需清除其属性(以防任何先前固定的范围“感染”它)并用默认属性替换它们。之后,super.processEditing() 执行它的工作并修复该范围内的任何新缺失字符(如果有的话)。

另一方面,如果您希望能够将样式化的文本粘贴到您的 TextView 中,应该可以通过比较 fixAttributesInRange 的之前/之后来跟踪您的固定范围,并且然后防止这些样式转移到 processEditing 中新键入的文本。

关于ios - NSTextStorage 子类在某些情况下无法处理表情符号字符和更改字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36899193/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com