我想用开放源代码twemoji替换UILable或UITextView中的所有标准iOS表情符号。
我在iOS中找不到任何库或文档来执行此操作。有没有人有一个解决方案,不涉及我从头开始实现这个?
解决方案需要高效且脱机工作。
答案 0 :(得分:3)
这个问题引起了我的兴趣,经过一些搜索,如何用自定义集替换所有标准iOS表情符号,我注意到即便是Twitter自己的iOS应用程序不使用Twemoji:
最后,我得出了与你相同的结论:
我无法在iOS中找到任何库或文档。
它为您完成所有工作,但如果您想实施自己的解决方案,我将在下面介绍如何用Twemoji替换所有标准表情符号。
有1126个基本字符具有表情符号表示,以及由序列形成的超过一千个其他表示。尽管大多数基本字符仅限于六个Unicode blocks,但除了其中一个块之外的所有块都与非表情符号字符和/或未分配的代码点混合在一起。这些块之外的其余基本字符分散在其他各个块中。
我的实现只是为这些字符声明了UTF-32代码点,因为value
的{{1}}属性就是这样。
在Swift中,UnicodeScalar
包含String
个对象的集合,每个对象代表一个extended grapheme cluster。扩展字形集群是一系列Unicode标量,它们共同代表一个 1 人类可读字符,这很有用,因为您可以循环遍历字符串的Character
并基于它来处理它们它们包含的Character
(而不是looping through the UTF-16 values of the string)。
要确定UnicodeScalar
是否为表情符号,只有第一个Character
是重要的,因此将此值与表情符号字符表进行比较就足够了。不过,我还建议您检查UnicodeScalar
是否包含Variation Selector,如果包含Twemoji,请确保它是否为VS16 - 否则该字符不会被呈现作为表情符号。
从Character
中提取UnicodeScalar
需要一个小小的黑客:
Character
flags图像根据其对应的代码点 2 命名,这是有道理的。因此,下一步是将let c: Character = "A"
let scalars = String(c).unicodeScalars
转换为与图像名称等效的字符串:
Character
很好,但这不适用于keycaps或zero-width joiners,因此我们必须修改我们的代码才能将其考虑在内:
let codePoint = String("").unicodeScalars.first!.value // 128579
let imageName = String(codePoint, radix: 16) // "1f643"
为了替换给定let scalars = String("").unicodeScalars
let filtered = scalars.filter{ $0.value != 0xfe0f } // Remove VS16 from variants, including keycaps.
let mapped = filtered.map{ String($0.value, radix: 16) }
let imageName = mapped.joined(separator: "-") // "1f1e7-1f1ea"
中的表情符号,我们需要使用String
来存储原始字符串,并将表情符号替换为包含NSMutableAttributedString
的{{1}}个对象。相应的Twemoji图像。
NSTextAttachment
要显示生成的属性字符串,只需将其设置为let originalString = ""
let attributedString = NSMutableAttributedString(string: originalString)
for character in originalString.characters {
// Check if character is emoji, see section 2.
...
// Get the image name from the character, see section 3.
let imageName = ...
// Safely unwrapping to make sure the image exists.
if let image = UIImage(named: imageName) {
let attachment = NSTextAttachment()
attachment.image = image
// Create an attributed string from the attachment.
let twemoji = NSAttributedString(attachment: attachment)
// Get the range of the character in attributedString.
let range = attributedString.mutableString.range(of: String(character))
// Replace the emoji with the corresponding Twemoji.
attributedString.replaceCharacters(in: range, with: twemoji)
}
}
/ attributedText
的{{1}}属性。
请注意,上述方法并未考虑modifier sequences或see here.,但我觉得这个答案已经太久了。
1.有UITextView
类型的怪癖将一系列连接的区域指示符符号解释为一个对象,尽管包含理论上无限量的Unicode标量。在操场上试试UILabel
。
功能
2.当涉及零宽度连接器和变化选择器时,命名模式会略有不同,因此从图像名称中删除它们会更容易 - {{3}} 功能
答案 1 :(得分:-2)
最简单的事情:
1)将twemoji图像加载到项目中。 2)创建一个NSDictionary,它将iOS支持的表情符号代码与相应的twemoji图像的路径相关联:
NSArray *iOSEmojis = @[@"iOSEmoji1",@"iOSEmoji2];
NSDictionary *twemojiPaths = [NSDictionary dictionaryWithObjects:@[@"Project/twemoji1.png",@"Project/twemoji2.png"] andKeys:@[@"iOSEmoji1","iOSEmoji2"]];
3)编写您的应用程序以搜索表情符号字符串并显示常规表情符号所在的twemojis:
for (NSString *emoji in iOSEmojis)
{
NSString *twemojiPath = [twemojiPaths valueForKey:emoji];
// Find the position of the emoji string in the text
// and put an image view there.
NSRange range = [label.text rangeOfString:emoji];
NSString *prefix = [label.text substringToIndex:range.location];
CGSize prefixSize = [prefix sizeWithAttributes: @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:14]}];
CGSize emojiSize = [label.text sizeWithAttributes: @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:14]}];
CGRect imageViewFrame = CGRectMake(prefixSize.width,label.frame.size.height,emojiSize.width,label.frame.size.height);
imageViewFrame = [self.view convertRect:imageViewFrame fromView:label];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageViewFrame];
imageView.image = [UIImage imageWithContentsOfFile:twemojiPath];
}