0

I have text which contains emoji in it, we are able to display it correctly by doing encoding and decoding the string, what I need to achieve is to increase the font size of only emoji in the text like in image below,

enter image description here

I have got an idea to determine the range of all emoji, and supply in NSAttributedString with increased font size. Now am out of idea how can I detect range of emojis in a given string?

Thanks

caldera.sac
  • 4,918
  • 7
  • 37
  • 69
iphonic
  • 12,615
  • 7
  • 60
  • 107

5 Answers5

2

I have done the same like

    let string = "This is emoji Test"
    let attributedEmoji = NSMutableAttributedString(string: " \u{1F600}", attributes: [NSFontAttributeName:UIFont.systemFontOfSize(60)])

    let attribString = NSMutableAttributedString.init(string: string)
    attribString.appendAttributedString(attributedEmoji)

    lblEmoji.attributedText = attribString

You can change the font and font size to scale the emoji.

See my output

  1. Put all possible Emoji's(Your application uses) into an array.
  2. Search for emoji into string from array.If found apply attributed Emoji.
  3. Write a method that accept emoji code and return attributed emoji text.

Hope this info will help you in better way.

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

Find out if Character in String is emoji?

Community
  • 1
  • 1
Raj Aggrawal
  • 761
  • 1
  • 6
  • 21
1

you can use it directly like below or

if ([myString containsString:@""]) 
   {
        NSLog(@"one");
        //change the font size here.
   }
else
   {
        NSLog(@"fk");
       //change the font size here.
   }

or you can use

[mystring is isEqualToString:"I believe "];

try those. hope this will help to you.

Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
caldera.sac
  • 4,918
  • 7
  • 37
  • 69
1

I have made one demo, You can detect emoji from the string like below,

  NSString *str = @"this is  and test ";

NSArray *arr = [str componentsSeparatedByString:@" "];

for (int i = 0; i < arr.count; i++) {

NSString *temp = [arr objectAtIndex:i];

if ( ![temp canBeConvertedToEncoding:NSASCIIStringEncoding]) {

    NSLog(@"%d",i);
    NSLog(@"%@",temp);  // temp is emoji. You can detect emoji here from your string now you can manage as per your need


}


}
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • How the above code will increase the FONT SIZE of emoji? – iphonic Aug 24 '16 at 09:56
  • Thanks, but what is `canBeConvertedToEncoding` can you put up full code? – iphonic Aug 24 '16 at 10:53
  • You're welcome...:) `canBeConvertedToEncoding` will return YES if string can be convertible to specified encoding (i.e. `NSASCIIStringEncoding` ) else it will return NO. S0, when emoji will come it will return NO. – Ketan Parmar Aug 24 '16 at 10:56
0

Thanks to all who answered, but none was complete answer though @Raj's suggestion to look NSString-RemoveEmoji helped me to achieve the solution for this, here it is, it works for any kind of emoji

-(NSMutableAttributedString *)getAttributedEmojiString:(NSString *)inputString{

    NSMutableArray *__block emojiRange=[[NSMutableArray alloc] init];
    [inputString enumerateSubstringsInRange:NSMakeRange(0, [inputString length])
                                    options:NSStringEnumerationByComposedCharacterSequences
                                 usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
             if([substring isEmoji]){
                 [emojiRange addObject:@{@"startrange":@(substringRange.location),@"endrange":@(enclosingRange.length)}];
             }
     }];

    NSMutableAttributedString *mutString=[[NSMutableAttributedString alloc] initWithString:inputString];


    [mutString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16.0] range:NSMakeRange(0, mutString.length)];

    [emojiRange enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [mutString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:35.0] range:NSMakeRange([obj[@"startrange"] floatValue], [obj[@"endrange"] floatValue])];
    }];

    return mutString;
}

Description

  1. First find NSRange of all the emoji in the string by using NSString-RemoveEmoji function isEmoji, and store in array.
  2. Supply the fetched range to apply bigger FONT SIZE to characters in the range.
  3. Finally assign the generated attributed text to the label.

    self.label.attributedText=[self getAttributedEmojiString:EmojiDecoded(originalText)];
    

I use two macros to Encode and Decode Emoji's since I need to save these values to server and read through api, below are the macros.

#define Encoded(val) [[val dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]
#define Decoded(val) [[NSString alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:val options:0] encoding:NSUTF8StringEncoding]

#define EmojiEncoded(val) [[NSString alloc] initWithData:[val dataUsingEncoding:NSNonLossyASCIIStringEncoding] encoding:NSUTF8StringEncoding]
#define EmojiDecoded(val) [[NSString alloc] initWithData:[val dataUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding]

Hope it helps anyone who is looking for similar solution.

Cheers, and thanks to all.

iphonic
  • 12,615
  • 7
  • 60
  • 107
  • how did you convert find emojis method , please share – Mridul Gupta Apr 27 '17 at 17:32
  • @MridulGupta I don't remember exactly but I didn't convert anything, I used NSString+RemoveEmoji category in my answer to determine if the string is emoji or not, if yes saving the range of the string and increasing font size. My answer is complete there is nothing extra. – iphonic Apr 27 '17 at 17:46
  • Is there a Objective-C implementation of the `isEmoji` method? – mengxiangjian Jun 18 '19 at 08:21
  • @mengxiangjian It is ObjectiveC only, you can define in function instead of `#define` – iphonic Jun 19 '19 at 11:37
0

This is somewhat late but might be useful for other folks who stumble upon this answer. The secret is to ask Core Text and it knows which characters in the NSAttributedString are emoji characters.

// Build the attributed string as needed
let ns = NSAttributedString(string: s)

// Now create a typesetter and render the line
let typesetter = CTTypesetterCreateWithAttributedString(nsa)
let line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, nsa.length))

// Once you have a line you can enumerate the runs
guard let runs = CTLineGetGlyphRuns(line) as? [CTRun] else {
    throw NSError(domain: "CoreText", code: -1, userInfo: nil)
}

// Each run will have a font with specific attributes
print("There are \(runs.count) run(s) in \(ns.string)")
print()
for run in runs {
    let charRange = CTRunGetStringRange(run)
    let x: NSAttributedString = CFAttributedStringCreateWithSubstring(nil, nsa, charRange)

    print("    Chars: '\(x.string)'")

    let attributes: NSDictionary = CTRunGetAttributes(run)
    let font = attributes["NSFont"] as! CTFont

    let traits = CTFontGetSymbolicTraits(font)
    print("    Emoji == \(traits.contains(.traitColorGlyphs))")

    print()
}
Jeremy Wiebe
  • 3,894
  • 22
  • 31