Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILabel italic font clipping

I'm trying to solve this problem as in the application I'm working on I have a lot of fonts, so size of label is being calculated dynamically when user changes font.

The problem that I have is that UILabel is being clipped at the end if font is Italic like on picture bellow:

UILabel clipping example

This is what I have tried so far:

  • calculating of width with the help of CoreText and CGSize CTFramesetterSuggestFrameSizeWithConstraints ( CTFramesetterRef framesetter, CFRange stringRange, CFDictionaryRef frameAttributes, CGSize constraints, CFRange *fitRange );
  • calculating of width with the help of NSAttributedString and - (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context
  • calculating of width with the help of NSString and - (CGSize)sizeWithAttributes:(NSDictionary<NSString *,id> *)attrs
  • using temp UITextView and sizeThatFits´ andfitToSize`

As there is a lot of fonts in application I need to set width of label dynamically, so subclassing of UILabel and adding few more points on drawFrameInRect is not working.

Here is sample code on Github.

Any help/advice is appreciated.

like image 245
Amar Kulo Avatar asked Nov 29 '15 17:11

Amar Kulo


2 Answers

CGSize size = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0f]}];
CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));

And update the label's width and height from adjustedSize.Hope it works

like image 80
Mithun kumar Avatar answered Sep 30 '22 19:09

Mithun kumar


I downloaded your GitHub project, and it appears that UILabel and UITextField are definitely calculating the bounds of the text differently. So, I first tried assigning the resulting size from sizeToFit on UITextField to the size of the UILabel. However, this approach breaks for the Strato font.

After trying some other approaches that failed, I remembered that italicized fonts sit at more or less the same angle. The italicized version of the font will usually increase the width of the bounding box by the same proportion to the original width.

Update:

Therefore, you should be able to derive the width of an italicized string from its width and font size. I've tried this approach in your project, and it works for all the fonts that you listed. I used the following formula:

CGRect calculatedRect = [attributedString boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) context:nil];

calculatedRect.size.width = calculatedRect.size.width + (label.font.pointSize * 0.2);

Since this depends on the added width due to italicization, italicizing bold fonts, such as Strata will have a greater impact on the width.

Obviously, if and when the text API is augmented to include reliable calculations for text width, you will be able to adopt it. However, the workaround I've presented may still be a better choice, if you want to have backward compatibility.

I hope that helps!

like image 45
Sheamus Avatar answered Sep 30 '22 20:09

Sheamus