Detect if a user has typed an emoji character in UITextView

前端 未结 9 1593
醉话见心
醉话见心 2020-12-05 08:13

I have a UITextView and I need to detect if a user enters an emoji character.

I would think that just checking the unicode value of the newest character would suffic

相关标签:
9条回答
  • 2020-12-05 08:48

    if your do not want your keyboard to show emoji you can use YOURTEXTFIELD/YOURTEXTVIEW.keyboardType = .ASCIICapable
    This will show a keyboard with no emoji

    0 讨论(0)
  • 2020-12-05 08:48

    Here is the emoji detection method in Swift. It works fine. Hope it will help others.

     func isEmoji(_ character: String?) -> Bool {
    
            if character == "" || character == "\n" {
                return false
            }
            let characterRender = UILabel(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
            characterRender.text = character
            characterRender.backgroundColor = UIColor.black  
            characterRender.sizeToFit()
            let rect: CGRect = characterRender.bounds
            UIGraphicsBeginImageContextWithOptions(rect.size, true, 0.0)
    
            if let contextSnap:CGContext = UIGraphicsGetCurrentContext() {
                characterRender.layer.render(in: contextSnap)
            }
    
            let capturedImage: UIImage? = (UIGraphicsGetImageFromCurrentImageContext())
            UIGraphicsEndImageContext()
            var colorPixelFound:Bool = false
    
            let imageRef = capturedImage?.cgImage
            let width:Int = imageRef!.width
            let height:Int = imageRef!.height
    
            let colorSpace = CGColorSpaceCreateDeviceRGB()
    
            let rawData = calloc(width * height * 4, MemoryLayout<CUnsignedChar>.stride).assumingMemoryBound(to: CUnsignedChar.self)
    
                let bytesPerPixel:Int = 4
                let bytesPerRow:Int = bytesPerPixel * width
                let bitsPerComponent:Int = 8
    
                let context = CGContext(data: rawData, width: Int(width), height: Int(height), bitsPerComponent: Int(bitsPerComponent), bytesPerRow: Int(bytesPerRow), space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue)
    
    
    
            context?.draw(imageRef!, in: CGRect(x: 0, y: 0, width: width, height: height))
    
                var x:Int = 0
                var y:Int = 0
                while (y < height && !colorPixelFound) {
    
                    while (x < width && !colorPixelFound) {
    
                        let byteIndex: UInt  = UInt((bytesPerRow * y) + x * bytesPerPixel)
                        let red = CGFloat(rawData[Int(byteIndex)])
                        let green = CGFloat(rawData[Int(byteIndex+1)])
                        let blue = CGFloat(rawData[Int(byteIndex + 2)])
    
                        var h: CGFloat = 0.0
                        var s: CGFloat = 0.0
                        var b: CGFloat = 0.0
                        var a: CGFloat = 0.0
    
                        var c = UIColor(red:red, green:green, blue:blue, alpha:1.0)
                        c.getHue(&h, saturation: &s, brightness: &b, alpha: &a)
    
                        b = b/255.0
    
                        if Double(b) > 0.0 {
                            colorPixelFound = true
                        }
                        x+=1
                    }
                    x=0
                    y+=1
                }
    
            return colorPixelFound
    }
    
    0 讨论(0)
  • 2020-12-05 08:50

    Another solution: https://github.com/woxtu/NSString-RemoveEmoji

    Then, after import this extension, you can use it like this:

    - (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;
    }
    

    Hope that helps ;)

    0 讨论(0)
  • 2020-12-05 09:05

    Emoji characters length is 2 and so check if string length is 2 in method that is shouldChangeTextInRange: that is called after each key on keyboard hit

    - (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;
    }
    
    } 
    
    0 讨论(0)
  • 2020-12-05 09:07

    Well you can detect whether it only has ascii characters using this:

    [myString canBeConvertedToEncoding:NSASCIIStringEncoding];
    

    It will say no if it fails (or has emoji). Then you can do a if else statement that does not allow them to click enter or something.

    0 讨论(0)
  • 2020-12-05 09:08

    The following are cleaner and more efficient implementations of the code that checks to see if the drawn character has any color or not.

    These have been written as category/extension methods to make them easier to use.

    Objective-C:

    NSString+Emoji.h:

    #import <Foundation/Foundation.h>
    
    @interface NSString (Emoji)
    
    - (BOOL)hasColor;
    
    @end
    

    NSString+Emoji.m:

    #import "NSString+Emoji.h"
    #import <UIKit/UIKit.h>
    
    @implementation NSString (Emoji)
    
    - (BOOL)hasColor {
        UILabel *characterRender = [[UILabel alloc] initWithFrame:CGRectZero];
        characterRender.text = self;
        characterRender.textColor = UIColor.blackColor;
        characterRender.backgroundColor = UIColor.blackColor;//needed to remove subpixel rendering colors
        [characterRender sizeToFit];
    
        CGRect rect = characterRender.bounds;
        UIGraphicsBeginImageContextWithOptions(rect.size, YES, 1);
        CGContextRef contextSnap = UIGraphicsGetCurrentContext();
        [characterRender.layer renderInContext:contextSnap];
        UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        CGImageRef imageRef = capturedImage.CGImage;
        size_t width = CGImageGetWidth(imageRef);
        size_t height = CGImageGetHeight(imageRef);
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        size_t bytesPerPixel = 4;
        size_t bitsPerComponent = 8;
        size_t bytesPerRow = bytesPerPixel * width;
        size_t size = height * width * bytesPerPixel;
        unsigned char *rawData = (unsigned char *)calloc(size, sizeof(unsigned char));
        CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                     bitsPerComponent, bytesPerRow, colorSpace,
                                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        CGColorSpaceRelease(colorSpace);
    
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
        CGContextRelease(context);
    
        BOOL result = NO;
        for (size_t offset = 0; offset < size; offset += bytesPerPixel) {
            unsigned char r = rawData[offset];
            unsigned char g = rawData[offset+1];
            unsigned char b = rawData[offset+2];
    
            if (r || g || b) {
                result = YES;
                break;
            }
        }
    
        free(rawData);
    
        return result;
    }
    
    @end
    

    Example usage:

    if ([@"                                                                    
    0 讨论(0)
提交回复
热议问题