11

これで文字列のテキストサイズを取得しています

textSize = [[tempDict valueForKeyPath:@"caption.text"] sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(280, CGFLOAT_MAX) lineBreakMode: NSLineBreakByWordWrapping];

唯一の問題は、文字列に絵文字しか含まれていない場合、アプリがクラッシュすることです。絵文字をチェックする簡単な方法はありますか、それとも考えられるすべての絵文字を含む配列を作成し、それを使用してそれらをチェックする必要がありますか?

エラー:

-[NSNull sizeWithFont:constrainedToSize:lineBreakMode:]: unrecognized selector sent to instance 0x3aa88a60


if ([tempDict valueForKeyPath:@"caption.text"]){
            NSLog(@"%@", [tempDict valueForKeyPath:@"caption"]);
            //Measure the message label box height
            textSize = [[tempDict valueForKeyPath:@"caption.text"] sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(280, CGFLOAT_MAX) lineBreakMode: NSLineBreakByWordWrapping];
            int height = 320 + 20 + textSize.height;
            [cellHeight addObject:[NSNumber numberWithInt:height]];
}
4

11 に答える 11

12

このコードを試してください:

- (BOOL)stringContainsEmoji:(NSString *)string {
    __block BOOL returnValue = NO;
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {

         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
             }

         } else {
             // non surrogate
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
             }
         }
     }];

    return returnValue;
}
于 2014-04-09T08:06:56.853 に答える
9

@ Simha.ICの答えは素晴らしいです。

ただし、新しい iOS 9.1 絵文字では機能しません。

Simha.IC スニペットは次のものを検出しません:
☂️✝️✡️☯️

この問題を解決するために、コードを少し調整して、カテゴリを作成しました。

- (BOOL)emo_containsEmoji
{
    __block BOOL containsEmoji = NO;

    [self enumerateSubstringsInRange:NSMakeRange(0,
                                                 [self length])
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring,
                                       NSRange substringRange,
                                       NSRange enclosingRange,
                                       BOOL *stop)
     {
         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs &&
             hs <= 0xdbff)
         {
             if (substring.length > 1)
             {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc &&
                     uc <= 0x1f9c0)
                 {
                     containsEmoji = YES;
                 }
             }
         }
         else if (substring.length > 1)
         {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3 ||
                 ls == 0xfe0f ||
                 ls == 0xd83c)
             {
                 containsEmoji = YES;
             }
         }
         else
         {
             // non surrogate
             if (0x2100 <= hs &&
                 hs <= 0x27ff)
             {
                 containsEmoji = YES;
             }
             else if (0x2B05 <= hs &&
                      hs <= 0x2b07)
             {
                 containsEmoji = YES;
             }
             else if (0x2934 <= hs &&
                      hs <= 0x2935)
             {
                 containsEmoji = YES;
             }
             else if (0x3297 <= hs &&
                      hs <= 0x3299)
             {
                 containsEmoji = YES;
             }
             else if (hs == 0xa9 ||
                      hs == 0xae ||
                      hs == 0x303d ||
                      hs == 0x3030 ||
                      hs == 0x2b55 ||
                      hs == 0x2b1c ||
                      hs == 0x2b1b ||
                      hs == 0x2b50)
             {
                 containsEmoji = YES;
             }
         }
     }];

    return containsEmoji;
}

私のカテゴリは次のように計算できます:

  • 文字列に絵文字がある場合
  • 絵文字の数
  • すべての絵文字の範囲

例として、カテゴリを使用して小さなプロジェクトを作成しました。

試してみたいカテゴリのポッドも作成しました。

于 2016-01-07T15:41:35.680 に答える
2

これは私が使用しているものです:

func isAllEmoji(aString: String) -> Bool {
    for scalar in aString.unicodeScalars {
        switch scalar.value {
        case 0x1F600...0x1F64F, // Emoticons
        0x1F300...0x1F5FF, // Misc Symbols and Pictographs
        0x1F680...0x1F6FF, // Transport and Map
        0x2600...0x26FF,   // Misc symbols
        0x2700...0x27BF,   // Dingbats
        0xFE00...0xFE0F,   // Variation Selectors
        0x0030...0x0039,
        0x00A9...0x00AE,
        0x203C...0x2049,
        0x2122...0x3299,
        0x1F004...0x1F251,
        0x1F910...0x1F990:
            break
        default:
            return false
        }
    }
    return true
}

いくつかの絵文字範囲が欠落していたこれを取得し、この絵文字配列を使用して、反復によって欠落しているランテを見つけました...詳細なテストは行っていません。

于 2016-07-14T23:09:16.610 に答える
0

iOS 10の新しいリリースでは、次の絵文字では機能しません。

絵文字

次のコード スニペットは、iOS 9 と iOS 10 の両方で試行およびテストされています。

extension String {

    var containsEmoji: Bool {
        for scalar in unicodeScalars {
            switch scalar.value {
            case 0x1F600...0x1F64F, // Emoticons
            0x1F300...0x1F5FF, // Misc Symbols and Pictographs
            0x1F680...0x1F6FF, // Transport and Map
            0x2600...0x26FF,   // Misc symbols
            0x2700...0x27BF,   // Dingbats
            0xFE00...0xFE0F,   // Variation Selectors
            0x1F910...0x1F918, // New Emoticons
            0x1F1E6...0x1F1FF, // Flags
            0x1F980...0x1F984,
            0x1F191...0x1F19A,
            0x1F201...0x1F202,
            0x1F232...0x1F23A,
            0x1F250...0x1F251,
            0x23E9...0x23F3,
            0x23F8...0x23FA,
            0x1F170...0x1F171,
            0x1F17E,
            0xA9,
            0xAE,
            0x2122,
            0x2328,
            0x3030,
            0x1F0CF,
            0x1F18E,
            0x1F9C0:
                return true
            default:
                continue
            }
        }
        return false
    }
}

上記のように、アプリで String 拡張機能を作成します。

そして、次のように使用できます。

if string.containsEmoji {
    // Do operations here
}
于 2016-10-10T07:08:21.273 に答える
0

この回答を参照してください。NSString に絵文字が含まれている場合に NSString のサイズを取得する方法は?

絵文字しかない場合は、 を使用しないでくださいsizeWithFont。それまたは何か他のものにラベルを使用してください。

NSString は絵文字では機能せず、テキストのみで機能します。絵文字がある場合は、[label sizeToFit]またはを使用する必要があります[label sizeThatFits:]

また、次のコードを使用できます。

 id text = [tempDict valueForKeyPath:@"caption.text"]

 if (![text isKindOfClass:[NSNull class]]) {
 ...
 }

辞書から NSNull を取得しますが、nil と等しくなく、条件が機能するためです。

于 2013-11-10T06:04:50.890 に答える
-1

お気づきかもしれませんが、これらの絵文字検出方法はすべて、Apple が新しい絵文字を追加するたびに機能しなくなります。

ここで、現在および将来のすべての絵文字で機能するCGスキャンソリューションを作成しました:https://stackoverflow.com/a/14472163/2057171

私の知る限り、オンラインのどこかに投稿されたこの問題に対する唯一の実際の回答です。


-(BOOL)isEmoji:(NSString *)character {//argument can be character or entire string

    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;

}

次のように使用できます。

NSString *myString = @"Hello this contains  an emoji";

BOOL containsEmoji = [self isEmoji:myString];
if (containsEmoji) {
    NSLog(@"Contained Emoji");
} else {
    NSLog(@"Did not contain Emoji");
}
于 2017-02-23T23:22:18.193 に答える