ios - 检测用户是否在 UITextView 中输入了表情符号字符

标签 ios objective-c unicode detect emoji

我有一个 UITextView,我需要检测用户是否输入了表情符号字符。

我认为只检查最新字符的 unicode 值就足够了,但是对于新的 emoji 2s,一些字符分散在整个 unicode 索引中(即苹果新设计的版权和注册标志)。

也许与使用 NSLocale 或 LocalizedString 值检查字符的语言有关?

有人知道好的解决方案吗?

谢谢!

最佳答案

多年来,随着 Apple 添加带有新方法的新表情符号(例如通过使用其他字符预先诅咒一个角色构建的肤色表情符号)等,这些表情符号检测解决方案不断出现问题。

我终于崩溃了,只写了以下适用于所有当前表情符号的方法,也应该适用于所有 future 的表情符号。

该解决方案创建了一个带有字符和黑色背景的 UILabel。然后 CG 拍摄标签的快照,我扫描快照中的所有像素以查找任何非纯黑色像素。我添加黑色背景的原因是为了避免由于 Subpixel Rendering 而导致的错误着色问题。

该解决方案在我的设备上运行速度非常快,我每秒可以检查数百个字符,但应该注意的是,这是一个 CoreGraphics 解决方案,不应像使用常规文本方法那样大量使用。图形处理的数据量很大,因此一次检查数千个字符可能会导致明显的延迟。

-(BOOL)isEmoji:(NSString *)character {

    UILabel *characterRender = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
    characterRender.text = character;
    characterRender.backgroundColor = [UIColor blackColor];//needed to remove subpixel rendering colors
    [characterRender sizeToFit];

    CGRect rect = [characterRender bounds];
    UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
    CGContextRef contextSnap = UIGraphicsGetCurrentContext();
    [characterRender.layer renderInContext:contextSnap];
    UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGImageRef imageRef = [capturedImage CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    BOOL colorPixelFound = NO;

    int x = 0;
    int y = 0;
    while (y < height && !colorPixelFound) {
        while (x < width && !colorPixelFound) {

            NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;

            CGFloat red = (CGFloat)rawData[byteIndex];
            CGFloat green = (CGFloat)rawData[byteIndex+1];
            CGFloat blue = (CGFloat)rawData[byteIndex+2];

            CGFloat h, s, b, a;
            UIColor *c = [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
            [c getHue:&h saturation:&s brightness:&b alpha:&a];

            b /= 255.0f;

            if (b > 0) {
                colorPixelFound = YES;
            }

            x++;
        }
        x=0;
        y++;
    }

    return colorPixelFound;

}

关于ios - 检测用户是否在 UITextView 中输入了表情符号字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14329110/

相关文章:

ios - 如何在 swift 3 中发布原始数据?

ios - 为 GCD 操作设置超时

ios - 无法上传 iOS 模拟器版本以供 Facebook 应用审查

ios - Objective C - 无法缩放嵌入到 UIScrollView 中的 UIImageView

python - UnicodeEncodeError : 'latin-1' codec can't encode character

ios - 环球银行金融电信协会 : expand/collapse custom cell from UIswitch in the custom cell

ios - 如何在 UICollectionView 中居中行?

ios - Unwind segue - 返回多个 View

unicode - 如果 UTF-8 是 8 位编码,为什么需要 1-4 个字节?

vb.net - 为什么 '?' 在打印中文文本时显示为输出