Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSParagraphStyle line spacing ignored

Tags:

A simple test that is failed: Make a new project with just one subview (UITextView) and put the following in:

- (void)viewDidLoad {     [super viewDidLoad];      NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];     paragraphStyle.lineHeightMultiple = 50.f;     paragraphStyle.lineSpacing = 100.f;     paragraphStyle.minimumLineHeight = 200.f;     paragraphStyle.maximumLineHeight = 500.f;      UIFont *font = [UIFont fontWithName:@"AmericanTypewriter" size:24.f];      self.textView.attributedText = [[NSAttributedString alloc] initWithString:     @"This is a test.\n Will I pass?" attributes:     @{NSParagraphStyleAttributeName : paragraphStyle, NSFontAttributeName : font}]; } 

Line spacing is the same as if the attribute were not there. Has anything got this to work successfully? I put in ridiculous numbers just to show that it won't change...

like image 348
borrrden Avatar asked Sep 24 '12 09:09

borrrden


People also ask

How do you control line spacing in UILabel?

"Short answer: you can't. To change the spacing between lines of text, you will have to subclass UILabel and roll your own drawTextInRect, or create multiple labels." This is a really old answer, and other have already addded the new and better way to handle this..

What is line spacing in Swift?

Line spacing is the vertical distance between lines of text. Aim for about 140%-180% for optimal readability and accessibility. Limit line length to 70–80 characters. Font size should be minimum 16pt. The bigger the screen the bigger the text.


2 Answers

This is a bug in NSHTMLWriter which is the private class which UITextView uses to convert attributedText into HTML. Internally it displays this HTML via a UIWebDocumentView. Read more on the inner workings of UITextView in my writeup here: http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

The problem comes from an easy to miss speciality in the font CSS shorthand. If you specify a pixel size with the font shorthand then this sets BOTH the font-size as well as the line-height. Since NSHTMLWriter puts the font AFTER the line-height this causes the line-height to be cancelled out by the font size.

See here for my Radar which includes the full analysis of the bug: http://www.cocoanetics.com/2012/12/radar-uitextview-ignores-minimummaximum-line-height-in-attributed-string/

I suggest you file a bug report as well and mention my Radar #12863734.

like image 136
Cocoanetics Avatar answered Oct 14 '22 19:10

Cocoanetics


I don't know if this is enough for your purposes but I could adjust the line spacing by setting the minimum and maximum line height. Furthermore to use a font I put it into the font property of the text view rather than passing it as the value of NSFontAttributeName in the attributes dictionary. (Maybe this part is not (well) documented?)

About your attributes

lineSpacing is calculated from the bottom of the line to the bottom of the upper line and that space is constrained to values between minimumLineHeight and miximumLineHeight. What I am trying to say is that maybe some values in your attributes are cancelling or overriding others.

Also if you need to just adjust the spacing between line you probably don't need to use paragraphStyle.lineHeightMultiple :)

The code

This worked for me:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.minimumLineHeight = 35.f; paragraphStyle.maximumLineHeight = 35.f;  UIFont *font = [UIFont fontWithName:@"AmericanTypewriter" size:18.f]; NSString *string = @"This is a test.\nWill I pass?\n日本語のもじもあるEnglish\nEnglish y Español"; NSDictionary *attributtes = @{     NSParagraphStyleAttributeName : paragraphStyle, }; self.textView.font = font; self.textView.attributedText = [[NSAttributedString alloc] initWithString:string                                  attributes:attributtes]; 

Additional Notes

There seems to be a situation with Japanese/Chinesse and maybe other characters mixed with alphabet characters in the same line. It will make that line to have a bigger leading to solve that you need to set up the minimum and maximum line height as I did. You can see the problem when rendering my example without attributes.

like image 30
nacho4d Avatar answered Oct 14 '22 18:10

nacho4d