- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
// Detect if an Emoji is in the string "text"
if(text.isIncludingEmoji) {
// Show an UIAlertView, or whatever you want here
return NO;
}
return YES;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
// Detect if an Emoji is in the string "text"
if([text length]==2) {
// Show an UIAlertView, or whatever you want here
return YES;
}
else
{
return NO;
}
}
9条答案
按热度按时间g0czyy6m1#
多年来,这些表情符号检测解决方案不断突破,因为苹果增加了新的表情符号和新的方法(比如通过预先诅咒一个字符来构建肤色表情符号)等。
我终于崩溃了,只是写了下面的方法,适用于所有当前的表情符号,应该适用于所有未来的表情符号。
该解决方案创建了一个带有字符和黑色背景的UILabel。CG然后拍摄标签的快照,我扫描快照中的所有像素,以查找任何非纯黑色像素。我添加黑色背景的原因是为了避免由于Subpixel Rendering而导致的错误着色问题
该解决方案在我的设备上运行非常快,我可以每秒检查数百个字符,但应该注意的是,这是一个CoreGraphics解决方案,不应该像常规文本方法那样大量使用。图形处理是数据繁重的,因此一次检查数千个字符可能会导致明显的滞后。
*注:如果苹果要推出一个纯黑色的表情符号,这个技术可以通过运行两次来改进,一次是黑色字体和黑色背景,然后再用白色字体和白色背景,并对结果进行OR运算。
os8fio9y2#
首先,让我们解决你的“55357方法”* -以及为什么它适用于许多emoji字符。
在可可中,
NSString
是unichar
的集合,而unichar
只是unsigned short
的类型别名,与UInt16
相同。由于UInt16
是0xffff
,这排除了相当多的emoji能够适合一个unichar
,因为用于emoji的六个主要Unicode块中只有两个属于这个范围:这些区块包含113个表情符号,另外66个表情符号可以被表示为单个
unichar
,分布在其他区块中。然而,这179个字符只代表1126个表情符号基本字符的一小部分,其余的必须由多个unichar
表示。让我们分析一下你的代码:
实际情况是,您只是获取字符串的第一个
unichar
,虽然这适用于前面提到的179个字符,但当您遇到UTF-32字符时,它会中断,因为NSString
将所有内容转换为UTF-16编码。转换的工作原理是将UTF-32值替换为 surrogate pairs,这意味着NSString
现在包含两个unichar
。现在,我们来看看为什么55357,或者
0xd83d
,会出现在很多emoji表情中:当你只查看UTF-32字符的第一个UTF-16值时,你会得到高代理,每个代理都有1024个低代理。高代理0xd83d
的范围是U+1F 400-U+1F 7 FF,它从最大的emoji块Miscellaneous Symbols and Pictographs的中间开始(U+1F 300-U+1F 5 FF),并一直延伸到Geometric Shapes Extended(U+1F 780-U+1F 7 FF)-总共包含563个表情符号,以及333个非表情符号字符。因此,令人印象深刻的是,50%的emoji基本字符具有高代理
0xd83d
,但这些演绎方法仍然留下了384个emoji字符未处理,沿着至少给出了同样多的误报。那么,如何检测一个字符是否是emoji呢?
我最近回答了一个somewhat related question with a Swift implementation,如果你愿意,你可以看看如何在this framework中检测emoji,我创建它的目的是用自定义图像替换标准emoji。
无论如何,你可以做的是从字符中提取UTF-32码位,我们将根据the specification来做:
在😎
UITextView
中键入““将以下内容写入控制台:按照这种逻辑,只需将
character
的值与emoji代码点的数据源进行比较,就可以确切地知道该字符是否是emoji。附言
还有一些“不可见”字符,即Variation Selectors和zero-width joiners,也应该被处理,所以我建议研究这些字符以了解它们的行为。
q35jwt9p3#
另一个解决方案:https://github.com/woxtu/NSString-RemoveEmoji
然后,在导入此扩展后,您可以像这样使用它:
希望有帮助;)
yqyhoc1h4#
如果您不希望键盘显示emoji,可以使用
YOURTEXTFIELD/YOURTEXTVIEW.keyboardType = .ASCIICapable
这将显示没有表情符号的键盘
anauzrmj5#
以下是Swift中的emoji检测方法,运行正常,希望对其他人有帮助。
chy5wohz6#
下面是检查绘制的字符是否具有任何颜色的代码的更干净、更高效的实现。
这些方法被编写为类别/扩展方法,以使它们更易于使用。
Objective-C:
NSString+Emoji.h:
NSString+Emoji.m:
示例用法:
Swift:
String+Emoji.swift:
示例用法:
3duebb1j7#
Swift的String类型有一个属性isEmoji
最好检查文档中的isEmojiPresentation警告
https://developer.apple.com/documentation/swift/unicode/scalar/properties/3081577-isemoji
pcrecxhr8#
那么你可以使用这个来检测它是否只有ascii字符:
如果它失败了(或者有表情符号),它会说不。然后你可以做一个if else语句,不允许他们点击回车之类的。
deikduxw9#
Emoji字符长度为2,因此检查shouldChangeTextInRange方法中的字符串长度是否为2:在键盘上的每个键被点击后调用