Max Hudson
Max Hudson

Reputation: 10206

UILabel negative line spacing

I've got a UILabel and I want to make the line spacing less than 0 (so the text moves closer together rather than further away). What am I doing wrong?

    UIFont* customFont = [UIFont fontWithName:@"BebasNeue" size:70];
    NSString * text = @"Their \nIdeas";

    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
    NSMutableParagraphStyle *paragrahStyle = [[NSMutableParagraphStyle alloc] init];
    paragrahStyle.lineSpacing = -30;
    [attributedString addAttribute:NSParagraphStyleAttributeName value:paragrahStyle range:NSMakeRange(0, [text length])];

    UILabel *lbl1 = [[UILabel alloc] init];
    lbl1.frame = CGRectMake(120, 0, viewWidth, 300);
    lbl1.backgroundColor = [UIColor clearColor];
    lbl1.textColor = grayColor;
    lbl1.numberOfLines = 2;
    lbl1.attributedText = attributedString;
    lbl1.userInteractionEnabled = NO;
    lbl1.font = customFont;
    [view addSubview:lbl1];
    [lbl1 setTransform:CGAffineTransformMakeRotation(0.35)];

Upvotes: 9

Views: 6262

Answers (5)

Wagner De Paula
Wagner De Paula

Reputation: 31

Just a minor tweak to make things more configurable.

extension UILabel {
    public func setLineHeight(lineHeight: CGFloat, textAlignment: NSTextAlignment ) {
        guard let text = self.text else { return }
        let attributeString = NSMutableAttributedString(string: text)
        let styleLineHeight = self.font.pointSize - self.font.ascender + self.font.capHeight + lineHeight
        let style = NSMutableParagraphStyle()
            style.alignment = textAlignment
            style.maximumLineHeight = styleLineHeight
            style.minimumLineHeight = styleLineHeight
        let offset = self.font.capHeight - self.font.ascender + lineHeight * 0.5
        let range = NSMakeRange(0, text.count)
        attributeString.addAttribute(.paragraphStyle, value: style, range: range)
        attributeString.addAttribute(.baselineOffset, value: offset, range: range)
        self.attributedText = attributeString
    }
}

Upvotes: 3

fdelam
fdelam

Reputation: 11

I cleaned up Christ Stillwell's answer a little bit:


extension UILabel {
    public func zeroLineSpace() {
        guard let text = self.text else { return }
        let attributedString = NSMutableAttributedString(string: text)
        let style = NSMutableParagraphStyle()
        let lineHeight = self.font.pointSize - self.font.ascender + self.font.capHeight
        let offset = self.font.capHeight - self.font.ascender
        let range = NSRange(location: 0, length: attributedString.length)
        style.maximumLineHeight = lineHeight
        style.minimumLineHeight = lineHeight
        style.alignment = self.textAlignment
        attributedString.addAttribute(.paragraphStyle, value: style, range: range)
        attributedString.addAttribute(.baselineOffset, value: offset, range: range)
        self.attributedText = attributedString
    }
}

Upvotes: 0

Chris Stillwell
Chris Stillwell

Reputation: 10547

Building off of Eric Murphey's answer, I've created an extension in Swift 4 syntax.

extension UILabel{    
    public func zeroLineSpace(){
        let s = NSMutableAttributedString(string: self.text!)
        let style = NSMutableParagraphStyle()
        let lineHeight = self.font.pointSize - self.font.ascender + self.font.capHeight
        let offset = self.font.capHeight - self.font.ascender
        let range = NSMakeRange(0, self.text!.count)
        style.maximumLineHeight = lineHeight
        style.minimumLineHeight = lineHeight
        style.alignment = self.textAlignment
        s.addAttribute(.paragraphStyle, value: style, range: range)
        s.addAttribute(.baselineOffset, value: offset, range: range)
        self.attributedText = s
    }
}

Simply call it like so

myUiLabel.zeroLineSpace()

Upvotes: 7

Eric Murphey
Eric Murphey

Reputation: 1475

NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:labelText];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
CGFloat minMaxLineHeight = (font.pointSize - font.ascender + font.capHeight);
NSNumber *offset = @(font.capHeight - font.ascender);
NSRange range = NSMakeRange(0, labelText.length);
[style setMinimumLineHeight:minMaxLineHeight];
[style setMaximumLineHeight:minMaxLineHeight];
if (isCentered) {
    [style setAlignment:NSTextAlignmentCenter];
}
[attrString addAttribute:NSParagraphStyleAttributeName
                   value:style
                   range:range];
[attrString addAttribute:NSBaselineOffsetAttributeName
                   value:offset
                   range:range];

This should get you near zero spacing on the text and should be safe to use with any font type and size.

Upvotes: 24

Barbara R
Barbara R

Reputation: 1057

Please see the following documentation from Apple setLineSpacing - NSMutableParagraphStyle , value must not be negative

setLineSpacing: Sets the distance in points added between lines within the paragraph to aFloat.

 - (void)setLineSpacing:(CGFloat)aFloat

Discussion

This value must be nonnegative.

There are also methods related to the minimum and maximum height for lines… probably setting line space to 0 and modifying the height could help you to achieve the effect you want-

Upvotes: 7

Related Questions