用twitter开源twemoji替换iOS app表情符号

时间:2016-11-17 19:16:48

标签: ios emoji

我想用开放源代码twemoji替换UILable或UITextView中的所有标准iOS表情符号。

我在iOS中找不到任何库或文档来执行此操作。有没有人有一个解决方案,不涉及我从头开始实现这个?

解决方案需要高效且脱机工作。

2 个答案:

答案 0 :(得分:3)

这个问题引起了我的兴趣,经过一些搜索,如何用自定义集替换所有标准iOS表情符号,我注意到即便是Twitter自己的iOS应用程序不使用Twemoji:

tweet

最后,我得出了与你相同的结论:

  

我无法在iOS中找到任何库或文档。

因此,我为此目的创建了a framework in Swift

它为您完成所有工作,但如果您想实施自己的解决方案,我将在下面介绍如何用Twemoji替换所有标准表情符号。

1。记录可以表示为表情符号的所有字符

有1126个基本字符具有表情符号表示,以及由序列形成的超过一千个其他表示。尽管大多数基本字符仅限于六个Unicode blocks,但除了其中一个块之外的所有块都与非表情符号字符和/或未分配的代码点混合在一起。这些块之外的其余基本字符分散在其他各个块中。

我的实现只是为这些字符声明了UTF-32代码点,因为value的{​​{1}}属性就是这样。

2。检查角色是否为表情符号

在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

3。将代码点转换为正确的格式

flags图像根据其对应的代码点 2 命名,这是有道理的。因此,下一步是将let c: Character = "A" let scalars = String(c).unicodeScalars 转换为与图像名称等效的字符串:

Character

很好,但这不适用于keycapszero-width joiners,因此我们必须修改我们的代码才能将其考虑在内:

let codePoint = String("").unicodeScalars.first!.value  // 128579
let imageName = String(codePoint, radix: 16)              // "1f643"

4。替换字符串

中的表情符号

为了替换给定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 sequencessee 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];
}