23

I want to have two lines of text appear really close together (small line spacing) for a button. I have the following code:

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"50 WPM"];

NSMutableParagraphStyle *paragrapStyle = [[NSMutableParagraphStyle alloc] init];
paragrapStyle.alignment = NSTextAlignmentCenter;
paragrapStyle.lineSpacing = -10;

[string addAttribute:NSParagraphStyleAttributeName value:paragrapStyle range:NSMakeRange(0, string.length)];

UIFont *font1 = [UIFont systemFontOfSize:22.0];
[string addAttribute:NSFontAttributeName value:font1 range:NSMakeRange(0, string.length - 4)];

UIFont *font = [UIFont systemFontOfSize:15.0];
[string addAttribute:NSFontAttributeName value:font range:NSMakeRange(string.length - 3, 3)];

[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, string.length)];

[self.button setAttributedTitle:string forState:UIControlStateNormal];

But as linespacing can't be negative, it doesn't get nearly as close as I'd like it to be. It looks like this:

enter image description here

Is there any way to get them closer?

Doug Smith
  • 29,668
  • 57
  • 204
  • 388
  • Have you tried adjusting the paragraph style's `paragraphSpacing` and `paragraphSpacingBefore` properties? – Joshua Oct 26 '13 at 12:43
  • I tried under `paragraphStyle.lineSpacing = -10;` to set those attributes on `paragrapStyle` to 0 (as well as -10 afterword) and neither had any noticeable effect. – Doug Smith Oct 27 '13 at 19:01
  • @DougSmith you use negative value for line spacing as per apple doc. Try something like (0.0000001). – Exploring Oct 31 '13 at 15:08

5 Answers5

57

Well if you have an attribute string then everything should be possible. :) You just have to look more.

- (void)setMinimumLineHeight:(CGFloat)aFloat
- (void)setMaximumLineHeight:(CGFloat)aFloat

Try

[paragraphStyle setLineSpacing:0.0f];
[paragraphStyle setMaximumLineHeight:7.0f];

You will realise that maximumLineHeight is not maximumLineSpacing. ^^

This for example is with setMaximumLineHeight:12];

enter image description here

nscoding
  • 866
  • 1
  • 6
  • 10
3

Here a little extension in Swift3 which supports negative lineSpacing

extension UILabel {
    func set(lineSpacing: CGFloat, textAlignment: NSTextAlignment = NSTextAlignment.center) {
        if let text = self.text {
            let paragraphStyle = NSMutableParagraphStyle()
            if lineSpacing < 0 {
                paragraphStyle.lineSpacing = 0
                paragraphStyle.maximumLineHeight = self.font.pointSize + lineSpacing
            } else {
                paragraphStyle.lineSpacing = lineSpacing
            }
            let attrString = NSMutableAttributedString(string: text)
            attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
            self.attributedText = attrString
            self.textAlignment = textAlignment
        }
    }
}
rushelmet
  • 305
  • 2
  • 15
0

I would suggest reading up on TextKit that was introduced in iOS7. I do not have much experience from it, but I do know that it gives you a lot of possibilities when it comes to attributing your texts.

Daniel Larsson
  • 6,278
  • 5
  • 44
  • 82
  • There's a real lack of TextKit tutorials for something simple like this unfortunately. I feel lost in a sea of complexity. – Doug Smith Oct 24 '13 at 01:30
  • This is unfortunately true. Ray Wenderlich does awesome tutorials, perhaps you could try out his! http://www.raywenderlich.com/50151/text-kit-tutorial – Daniel Larsson Oct 24 '13 at 01:41
0

In Swift 3, you can achieve this by :

let paragraph = NSMutableParagraphStyle()
paragraph.lineSpacing = 0
paragraph.maximumLineHeight = 20.

Keep the lineSpacing = 0. You can adjust the maximumLineHeight to make it closer or to increase the spacing.

Joshua Cleetus
  • 624
  • 6
  • 14
-2

How about subclassing UIButton, and add 2 UILabels to the buttons view that are close together. Create properties for the labels and set approrpietly:

CustomButton *btn = [CustomButton new];

btn.textLine1 = @"Top";
btn.textLine2 = @"Bottom";

The only problem doing it this way is you will need to handle the text color when the state changes yourself.

RyanG
  • 4,393
  • 2
  • 39
  • 64