How to control the line spacing in UILabel
Solution 1
I thought about adding something new to this answer, so I don't feel as bad... Here is a Swift answer:
import Cocoa
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 40
let attrString = NSMutableAttributedString(string: "Swift Answer")
attrString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
var tableViewCell = NSTableCellView()
tableViewCell.textField.attributedStringValue = attrString
"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.. Please see the up to date answers provided below.
Solution 2
In Xcode 6 you can do this in the storyboard:
Solution 3
Starting from iOS 6 you can set an attributed string to the UILabel. Check the following :
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:label.text];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = spacing;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.text.length)];
label.attributedText = attributedString;
Solution 4
The solutions stated here didn't work for me. I found a slightly different way to do it with the iOS 6 NSAttributeString:
myLabel.numberOfLines = 0;
NSString* string = @"String with line one. \n Line two. \n Line three.";
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.minimumLineHeight = 30.f;
style.maximumLineHeight = 30.f;
NSDictionary *attributtes = @{NSParagraphStyleAttributeName : style,};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:string
attributes:attributtes];
[myLabel sizeToFit];
Solution 5
From Interface Builder (Storyboard/XIB):
Programmatically:
SWift 4
Using label extension
extension UILabel {
// Pass value for any one of both parameters and see result
func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {
guard let labelText = self.text else { return }
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = lineSpacing
paragraphStyle.lineHeightMultiple = lineHeightMultiple
let attributedString:NSMutableAttributedString
if let labelattributedText = self.attributedText {
attributedString = NSMutableAttributedString(attributedString: labelattributedText)
} else {
attributedString = NSMutableAttributedString(string: labelText)
}
// Line spacing attribute
attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
self.attributedText = attributedString
}
}
Now call extension function
let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) . // try values 1.0 to 5.0
// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0
Or using label instance (Just copy & execute this code to see result)
let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))
label.attributedText = attrString
Swift 3
let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString
Related videos on Youtube
Abhinav
Updated on February 12, 2021Comments
-
Abhinav about 3 years
Is it possible to reduce the gap between text, when put in multiple lines in a
UILabel
? We can set the frame, font size and number of lines. I want to reduce the gap between the two lines in that label.-
Suresh Varma over 11 yearspossible duplicate of How to increase a space between two lines in multiline label?
-
Mark Amery over 10 yearsMay I suggest that you accept one of the answers that is correct for iOS 6.0 and later? The currently accepted answer is out of date.
-
mfaani over 7 yearsFor each line use a new
UILabel
, then embed all labels in aStackView
. Finally adjust thespacing
ofStackView
. Remember to stack them vertically. -
Sneha over 7 yearsRefer the following link for solution in Swift 2. stackoverflow.com/a/39158698/6602495
-
lal about 6 yearsRefer to stackoverflow.com/a/44325650/342794 for storyboard tweak and other details.
-
-
ıɾuǝʞ over 11 yearsSince iOS 6.0, you can control it via
NSAttributedString
(also available in properties of UILable in Xcode's interface builder). -
Denis Kutlubaev over 11 yearsThis worked for me, thanks. I also tried to use MTLabel, but this one was better.
-
esreli almost 11 yearsDoes anyone know if MSLabel supports the '\n' character?
-
lothorp over 10 yearsInterestingly, as near as I can tell, you can add extra spacing between the lines, but not reduce it via the
NSParagraphStyle
when using anNSAttributedString
. (I may need to do more testing of the other modifyable properties, but thelineSpacing
property only allows you to increase it.) -
d.ennis over 10 yearssee my answer to see a way using NSAttributedString
-
infinity26 over 10 yearsLine height is font size dependent. Line spacing is just that, line spacing. You may get things to work out by just setting min/max line height, but that's only because the current font sizes you're using aren't greater than the line height boundaries. Per the documentation: "... glyphs and graphics exceeding this height will overlap neighboring lines ... Although this limit applies to the line itself, line spacing adds extra space between adjacent lines."
-
Mike S over 9 yearsThe
attributedString
must be anNSMutableAttributedString
(NOT NSAttributedString) -
Dom Vinyard over 9 years@livingtech That is infuriating, and I believe you are correct. Have you found any workarounds?
-
CodyMace over 9 yearsHere's what I did and it works great. This is using TTTAttributedLabel, but it should work for and AttributedString: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = 1; [mutableAttributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:whole];
-
Allen over 9 yearsTake more advantages of storyboard!
-
Allen over 9 yearsThe first line code should be
NSMutableAttributedString *attributedString = [NSMutableAttributedString alloc]initWithString:@"sample text"];
-
Zoyt over 9 yearsThis is exactly what I needed (I needed to compress the lines). Thanks a lot!
-
PaperThick over 9 yearsUsing this option seems to break my ib every time, does anyone know what the issue could be there?
-
Anton Gaenko over 9 years@PaperThick have the same issue in 6.1.1. It "harlem shake" for few minutes. Doesn't know how to fix it :) Xcode Shaking
-
Marcos Curvello about 9 yearsIs there a way to set custom fonts this way ? I can't seem to change that helvetica neue to any other font.
-
lawicko about 9 years+1, If you want to reduce the spacing between lines, this is what you want to do. The real line spacing is most likely 0 by default, this is why people report you can only increase it. The problem with spacing being too big comes from the line height being too big, this is why this will get the job done 99% of the time.
-
Fabien Warniez about 9 yearsUsing iOS 8.2 I was able to to reduce it. You can't set it to 0, however.
-
Theo almost 9 yearsThe
lineSpacing
property of theNSMutableParagraphStyle
is never negative, so the line height cannot be reduced with this approach. To answer the question, you have to use another property, see @d.ennis answer. -
Anconia almost 9 yearsThis is a great solution. Unfortunately Xcode continues to disappoint . . . freezes every time I open this box
-
andrew k almost 9 years@Anconia Indeed, an unworkable solution. I've found that switching back to a plain text label will crash Xcode 6.3.2. I had to delete the label and start again.
-
ED-209 almost 9 yearsXcode 6.3.1 when it Harlem Shakes it looks like its broken, but if you click elsewhere eventually it'll go away and all seems ok.
-
ED-209 almost 9 yearsIf you enable 'Attributed', and then open the file as source code you can edit the 'lineHeightMultiple' manually, and therefore bypass the Harlem Shake bug
-
Pichirichi over 8 years@Marcos it is only working in system font, there is a radar about it for several versions, at this stage customer fonts only work via the CODe and not from the interface builder.
-
dvs over 8 yearsThe shake bug is still there in Xcode 7.1.1. Careful what you do while it's shaking, Xcode will queue your clicks and keypresses and fire them all at once after it stops. I ended up having multiple source files modified and moved around. Edit the value directly in the storyboard XML to be safe until this absurd bug is fixed.
-
BigRon over 8 yearsStoryboard and I don't get along, but this is great. +1000
-
LulzCow about 8 years@azdev for anyone still looking at this, I'm on longer getting the shakes in Xcode 7.3, but I think this is the first version where it hasn't been a problem
-
virsunen almost 8 yearsJust to clarify something in this thread. If you want to shrink the line spacing set the line height to 1.0, and then setLineHeightMultiple to a lower value < 1.0, like: [paragraphStyle setLineHeightMultiple:0.8] or paragraphStyle.lineHeightMultiple = 0.8
-
mfaani over 7 years@MarcosCurvello My solution here is a workaround that may be useful.
-
mfaani over 7 yearsremember if you doing this while you are also using Storyboard for this label, then be sure to set your label's lines to 0
-
mfaani over 7 yearsWhy don't you just directly set the
lineSpacing
and forget about settinglineHeightMultiple
? -
Agustin Meriles over 7 yearsBecause the key to reduce the line height is 'lineHeightMultiple', no lineSpacing
-
mfaani over 7 yearssay you want your line height to be 1.4, why can't you just write
.lineSpacing = 1.4
and forget all about.lineHeightMultiple
... -
mfaani over 7 yearsHah! I tried, and I didn't work, but I wonder why I don't see other answers here not using your mechanism, I mean they just directly set the lineSpacing. See the accepted answer...
-
mfaani over 7 years1) why are mentioning
tableViewCell
is there any discussion about a tableView or a cell? 2) when we are changing the layout, why don't we need to call 'setNeedsDisplay' again? -
Mazyod over 7 years@Honey A UI element is required to see the feature in action. Any will do. Other answers use
UILabel
, I usedNSTextField
within aNSTableCellView
. Layout and drawing are separate things.setNeedsDisplay
is for drawing and rendering updates. -
Albert Bori over 7 yearsThis is the only answer I could find that uses the actual line height value (instead of a ratio) common to design applications such as Photoshop, Sketch, CSS, etc.
-
UKDataGeek almost 7 yearsThis seems to push my uilabel downwards when i put it in a stackview- anyone have a working project?
-
Russell Warwick over 6 yearsThis should help with it. You can then assign your label to this custom class within the storyboard and use it's parameters directly within the properties.
-
Neuron over 6 yearsplease don't put content related to your answer in the comments. your answer should be helpful without having to read through the comments
-
mfaani over 5 yearsFWIW this is a terrible yet workable solution. Hence I'm keeping it.
-
Nithin Michael almost 5 yearsAdd the line " paragraphStyle.alignment = self.textAlignment" to keep the original alignment . Otherwise, the text will be left aligned.
-
iDeveloper over 4 yearsYou saved me friend :)
-
cabyambo over 4 yearsIt works, but you have to make sure you've already assigned text to the label. Otherwise it will crash when your code tries to unwrap the text attribute
-
christostsang about 4 yearsFor anyone loosing ellipsis on large texts, then use: paragraphStyle.lineBreakMode = .byTruncatingTail
-
Pavel Alexeev almost 4 yearsextra padding must be (lineHeightMultiple - 1.0) * font.pointSize, right?
-
phatmann almost 4 yearsThe code above as-is seemed to work for me. But maybe you are right. Did you try your change? @PavelAlexeev
-
Pavel Alexeev almost 4 yearsNo, I stick with lineSpacing instead of lineHeightMultiple :)
-
Shrikant Phadke almost 3 yearswhat worked for me is this. extension UILabel { func setLineHeight(lineHeight: CGFloat) { let text = self.text if let text = text { let attributedString = NSMutableAttributedString(string: text) let style = NSMutableParagraphStyle() style.lineHeightMultiple = lineHeight attributedString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: text.count)) self.attributedText = attributedString } } }
-
Wahab Khan Jadon almost 2 yearsThis solution works for me i just change
paragraphStyle.alignment = .center
toparagraphStyle.lineBreakMode = .byTruncatingTail paragraphStyle.baseWritingDirection = NSParagraphStyle.defaultWritingDirection(forLanguage: GeneralMethods.getSelectedLanguage().stringValue)
and its automatically adopt direction according to selected language.