您如何验证是否支持多代码点表情符号?
How can you verify a multiple code point emoji is supported?
对于上下文,我正在尝试创建从字符串代码点到表情符号的映射,并且需要知道系统是否支持表情符号:
("1F9AE") -> ""
("1FAE0") -> "" (iOS 15.4+) / nil (if below 15.4, since it would show as "")
("1F415-200D-1F9BA") -> ""
("1F415-1F9BA") -> nil (since it would normally be "", which isn't a single emoji)
我已经将其用于单代码点案例:
func emoji(for codepoint: String) -> String? {
guard let int = Int(codepoint, radix: 16),
let scalar = UnicodeScalar(int),
scalar.properties.isEmoji
else { return nil }
return String(scalar)
}
但是,我不知道对具有多个代码点的 isEmoji
的相应检查是什么。
// assume I had to make these scalars via a `String`
let scalars = [UnicodeScalar(0x1F415)!, UnicodeScalar(0x200D)!, UnicodeScalar(0x1F9BA)!]
let scalarView = String.UnicodeScalarView(scalars)
// How can I check that this `UnicodeScalarView` is for single, supported emoji, since I can't check `isEmoji`?
print(String(scalarView))
例如,"1FAE0-1F3FD"
应该是 nil
,因为它不是单个表情符号 (""
)。然而,在未来的版本中,融化的脸可能会与皮肤变化一起使用,在这种情况下,它应该 return 那个单一的有效表情符号。
根据表情符号 14.0 的 data files,表情符号可以是基本表情符号、键帽序列、旗帜、修饰符序列或 ZWJ 序列。在每一种情况下,序列中至少有一个代码点 isEmoji
returns true
,序列将形成一个字形。
因此,您应该首先从 unicode 标量中创建一个字符串:
let scalars = [UnicodeScalar(0x1F415)!, UnicodeScalar(0x200D)!, UnicodeScalar(0x1F9BA)!]
let scalarView = String.UnicodeScalarView(scalars)
let string = String(scalarView)
然后,你可以看看是不是这样的表情:
CTLineGetGlyphCount(CTLineCreateWithAttributedString(
NSAttributedString(string: string)
)) == 1 &&
string.unicodeScalars.contains { [=11=].properties.isEmoji }
或者,由于您只是想检查表情符号是否可以正常显示,您可以使用CTFontGetGlyphsForCharacters
查看Apple Color Emoji 是否支持这些字符。
let font = UIFont(name: "AppleColorEmoji", size: 20)! as CTFont
var text = Array(string.utf16)
var glyphs = Array(repeating: 0 as CGGlyph, count: text.count)
let isEmoji = CTFontGetGlyphsForCharacters(font, &text, &glyphs, text.count) &&
CTLineGetGlyphCount(CTLineCreateWithAttributedString(
NSAttributedString(string: string)
)) == 1
请注意,这两种方法都会 return 误报(non-emojis 就像 ASCII 字母被报告为表情符号),但不会 return 误报。
对于上下文,我正在尝试创建从字符串代码点到表情符号的映射,并且需要知道系统是否支持表情符号:
("1F9AE") -> ""
("1FAE0") -> "" (iOS 15.4+) / nil (if below 15.4, since it would show as "")
("1F415-200D-1F9BA") -> ""
("1F415-1F9BA") -> nil (since it would normally be "", which isn't a single emoji)
我已经将其用于单代码点案例:
func emoji(for codepoint: String) -> String? {
guard let int = Int(codepoint, radix: 16),
let scalar = UnicodeScalar(int),
scalar.properties.isEmoji
else { return nil }
return String(scalar)
}
但是,我不知道对具有多个代码点的 isEmoji
的相应检查是什么。
// assume I had to make these scalars via a `String`
let scalars = [UnicodeScalar(0x1F415)!, UnicodeScalar(0x200D)!, UnicodeScalar(0x1F9BA)!]
let scalarView = String.UnicodeScalarView(scalars)
// How can I check that this `UnicodeScalarView` is for single, supported emoji, since I can't check `isEmoji`?
print(String(scalarView))
例如,"1FAE0-1F3FD"
应该是 nil
,因为它不是单个表情符号 (""
)。然而,在未来的版本中,融化的脸可能会与皮肤变化一起使用,在这种情况下,它应该 return 那个单一的有效表情符号。
根据表情符号 14.0 的 data files,表情符号可以是基本表情符号、键帽序列、旗帜、修饰符序列或 ZWJ 序列。在每一种情况下,序列中至少有一个代码点 isEmoji
returns true
,序列将形成一个字形。
因此,您应该首先从 unicode 标量中创建一个字符串:
let scalars = [UnicodeScalar(0x1F415)!, UnicodeScalar(0x200D)!, UnicodeScalar(0x1F9BA)!]
let scalarView = String.UnicodeScalarView(scalars)
let string = String(scalarView)
然后,你可以看看是不是这样的表情:
CTLineGetGlyphCount(CTLineCreateWithAttributedString(
NSAttributedString(string: string)
)) == 1 &&
string.unicodeScalars.contains { [=11=].properties.isEmoji }
或者,由于您只是想检查表情符号是否可以正常显示,您可以使用CTFontGetGlyphsForCharacters
查看Apple Color Emoji 是否支持这些字符。
let font = UIFont(name: "AppleColorEmoji", size: 20)! as CTFont
var text = Array(string.utf16)
var glyphs = Array(repeating: 0 as CGGlyph, count: text.count)
let isEmoji = CTFontGetGlyphsForCharacters(font, &text, &glyphs, text.count) &&
CTLineGetGlyphCount(CTLineCreateWithAttributedString(
NSAttributedString(string: string)
)) == 1
请注意,这两种方法都会 return 误报(non-emojis 就像 ASCII 字母被报告为表情符号),但不会 return 误报。