AliSoftware / OHAttributedLabel

UILabel that supports NSAttributedString
https://github.com/AliSoftware/OHAttributedLabel/wiki
1.51k stars 344 forks source link

Normal label can display emoji, but not this label. Am i missing anything? #105

Closed HMSpaceo closed 10 years ago

HMSpaceo commented 11 years ago

I have done exactly same code which found in demo code but i cant display emoji . Can you please help me with this ?

clueckler commented 11 years ago

set extendBottomToFit = YES than you should see them, but i have problem with the alignment of them -.-

clueckler commented 11 years ago

Fixed it with replacing some code:

in OHAttributedLabel.m -->

Replaced "drawingRect.origin.y -= delta;" with "drawingRect.origin.y -= [self stringContainsEmoji:self.attributedText.string] ? delta * 0.7 : delta;"

And add this function to detect if string is emoji to OHAttributedLabel.m:

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

}

HMSpaceo commented 11 years ago

Its working...thanks a lot for the code.

franzwarning commented 11 years ago

This code is clutch. Thanks.

clueckler commented 11 years ago

I have detected another problem with my code snipplet: It only works if your text hat one line. If you have several lines and the text size is smaller than the emojis, the text will move out of the top/bottom of the label. When someone has an idea how to fix this problem .... then your welcome to tell it to me ;-)

AliSoftware commented 11 years ago

Actually that's why I didn't merge this workaround in the trunk, because it was some quick & dirty fix that does not take all the use cases into account. But from now on I don't really have a working solution myself.

The best solution for this is to make the label higher so that it has enough space to draw the emoji glyphs, but that's not really a satisfying solution either…

clueckler commented 11 years ago

Oh sry .... my fault ... had a problem with the calculation of the Label-Height .... ;-)

Today I had some time to look at this problem and now i come to this solution:

This works pretty well and also the alignment of the OHAttributedLabel is now correct =)

leejunkit commented 11 years ago

I don't know if this is expected behavior, but suggestedSize.width != width in my case. it gives some weird decimal that causes the label to draw a stray vertical line to the right of its frame. easily fixed though by setting the width explicitly in the label's frame instead of using suggestedSize.width

AliSoftware commented 10 years ago

I am closing this issue, as: