Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate UILabel height for text with different languages and emojis in Objective-C

I need to calculate the frame size for given text that may be in english/emoji/other languages.

The way I did it was:

NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByWordWrapping];
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:fontSize], NSParagraphStyleAttributeName: style};
CGSize rect = [text boundingRectWithSize:CGSizeMake(containerWidth, CGFLOAT_MAX)
                               options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
                            attributes:attributes
                               context:nil].size;

It works fine as long as I do not use emoji. It seems that the emoji line height/font size is different than regular fonts.

I saw that people tried solving it in different ways such as: http://youbbe.xyz/issue/4987325/ios-emoji-messed-up-in-uilabel

This solution works for emojis but not for English/other fonts.

See example image:

enter image description here

As you can see, just text is calculated fine (first box) but text+emoji is not calculated correctly (second box).

I'm really surprised that there is no easy solution for this problem. Your help is much appreciated.

like image 475
Code Monkey Avatar asked Mar 27 '16 13:03

Code Monkey


People also ask

How is UILabel height calculated?

To summarize, you can calculate the height of a label by using its string and calling boundingRectWithSize . You must provide the font as an attribute, and include . usesLineFragmentOrigin for multi-line labels.

How do I change label height in Swift?

To give a dynamic height to an UIlabel in swift we can use the frame property of UILabel. We can create a frame using the CGRect which allows us to give different variables like x position, y position, width, and height.


2 Answers

With a UILabel you can simply say:

CGSize size = [label sizeThatFits:CGSizeMake(containerWidth, CGFLOAT_MAX)];

Have you tried this? I don't think emoji have a different line height, but rather they typically take up the entire line height.

You can just say [label sizeToFit]; and then get the size from the frame, (e.g. CGSize size = label.frame.size;). This seems the most consistently accurate way of getting the right size for different font sizes.

There is some code here that you can copy and paste into a playground and see the different results.

like image 74
beyowulf Avatar answered Sep 28 '22 20:09

beyowulf


A possible solution is set text with attribute string and specify paragraph style

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 5;
paragraphStyle.lineHeightMultiple = 1.1;
paragraphStyle.maximumLineHeight = 16;

maximumLineHeight can limit height of line which has emoji in it.

like image 20
BB9z Avatar answered Sep 28 '22 22:09

BB9z