Setting font on NSAttributedString on UITextView disregards line spacing

Objective CIos6

Objective C Problem Overview


I'm trying to set an attributed string to a UITextView in iOS 6. The problem is, if I attempt to set the font property on the attributed string, the line spacing is ignored. However, if I don't set the font, and the default font is used, then line spacing works.

NSString *string = @" Hello \n world";
attrString = [[NSMutableAttributedString alloc] initWithString:string];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];

paragraphStyle.minimumLineHeight = 50;
// setting the font below makes line spacing become ignored
[attrString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:20] range:NSMakeRange(0, string.length)];
[attrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, string.length)];

mainTextView.attributedText = attrString;

Any idea what's going on?

Objective C Solutions


Solution 1 - Objective C

Attributed String Programming Guide:

UIFont *font = [UIFont fontWithName:@"Palatino-Roman" size:14.0];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:font
                                forKey:NSFontAttributeName];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"strigil" attributes:attrsDictionary];

Update: I tried to use addAttribute: method in my own app, but it seemed to be not working on the iOS 6 Simulator:

NSLog(@"%@", textView.attributedText);

The log seems to show correctly added attributes, but the view on iOS simulator was not display with attributes.

Solution 2 - Objective C

I found your question because I was also fighting with NSAttributedString. For me, the beginEditing and endEditing methods did the trick, like stated in [Changing an Attributed String][1]. Apart from that, the lineSpacing is set with setLineSpacing on the paragraphStyle.

So you might want to try changing your code to:

NSString *string = @" Hello \n world";
attrString = [[NSMutableAttributedString alloc] initWithString:string];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];

[paragraphStyle setLineSpacing:20]  // Or whatever (positive) value you like...    
[attrSting beginEditing];

[attrString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:20] range:NSMakeRange(0, string.length)];
[attrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, string.length)];

[attrString endEditing];

mainTextView.attributedText = attrString;

Didn't test this exact code though, btw, but mine looks nearly the same.

EDIT:

Meanwhile, I've tested it, and, correct me if I'm wrong, the - beginEditing and - endEditing calls seem to be of quite an importance.

[1]: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/AttributedStrings/Tasks/ChangingAttrStrings.html#//apple_ref/doc/uid/20000162-176048 "Changing an Attributed String"

Solution 3 - Objective C

//For proper line spacing

NSString *text1 = @"Hello";
NSString *text2 = @"\nWorld";
UIFont *text1Font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:10];
NSMutableAttributedString *attributedString1 =
[[NSMutableAttributedString alloc] initWithString:text1 attributes:@{ NSFontAttributeName : text1Font }];
NSMutableParagraphStyle *paragraphStyle1 = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle1 setAlignment:NSTextAlignmentCenter];
[paragraphStyle1 setLineSpacing:4];
[attributedString1 addAttribute:NSParagraphStyleAttributeName value:paragraphStyle1 range:NSMakeRange(0, [attributedString1 length])];

UIFont *text2Font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:16];
NSMutableAttributedString *attributedString2 =
[[NSMutableAttributedString alloc] initWithString:text2 attributes:@{NSFontAttributeName : text2Font }];
NSMutableParagraphStyle *paragraphStyle2 = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle2 setLineSpacing:4];
[paragraphStyle2 setAlignment:NSTextAlignmentCenter];
[attributedString2 addAttribute:NSParagraphStyleAttributeName value:paragraphStyle2 range:NSMakeRange(0, [attributedString2 length])];

[attributedString1 appendAttributedString:attributedString2];

Solution 4 - Objective C

There was a bug in iOS 6, that causes line height to be ignored when font is set. See answer to https://stackoverflow.com/questions/12562506/nsparagraphstyle-line-spacing-ignored and longer bug analysis at Radar: UITextView Ignores Minimum/Maximum Line Height in Attributed String.

Solution 5 - Objective C

You can use this example and change it's implementation like this:

[self enumerateAttribute:NSParagraphStyleAttributeName
                 inRange:NSMakeRange(0, self.length)
                 options:0
              usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {
                  NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];

                  //add your specific settings for paragraph
                  //...
                  //...

                  [self removeAttribute:NSParagraphStyleAttributeName range:range];
                  [self addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];
              }];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSnowmanView Question on Stackoverflow
Solution 1 - Objective CmaxengView Answer on Stackoverflow
Solution 2 - Objective CJan NashView Answer on Stackoverflow
Solution 3 - Objective CNitin MehtaView Answer on Stackoverflow
Solution 4 - Objective CPalimondoView Answer on Stackoverflow
Solution 5 - Objective ClandonandreyView Answer on Stackoverflow