How do I vertically align a UILabel in a UITableViewCell when using lineHeightMultiple to control leading lines?

I have a multi-line UILabel in a UITableViewCell. I want to control the distance between the lines in order to compress the lines a little closer together. I've read that the only way to manage this "master" is with attributed strings. So I did it by making the label an attribute instead of plain text, and then I set lineHeightMultiple to 0.7 to compress the lines:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple = 0.7;
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;

NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"HelveticaNeue-Bold" size:15.0], NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];

NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:@"Here is some long text that will wrap to two lines." attributes:attrs];

[cell.textLabel setAttributedText:attributedText];

      

The problem is that now the shared label is not vertically centered inside the UITableViewCell.

How can I fix this? In the attachment below you can see what I mean. The "squashed" multi-line UILabel is taller on each line than it should be and no longer vertically aligned with the arrow indicator on the right side.

example

+3


source to share


2 answers


Multiple line-height changes the line-height of all lines, including the first line, so it's all slightly higher on your label. What you really want is to adjust the line spacing, so the second line starting at the baseline is slightly closer than the default.

Try replacing:

paragraphStyle.lineHeightMultiple = 0.7;

      



from:

paragraphStyle.lineSpacing = -5.0;

      

Adjust the line spacing value to your liking.

+2


source


Both UITextDrawing

and Core Text

are doing it. I think these are super strings. Instead of using an arbitrary value for lineSpacing

- I will say that I am calculating this with Core Text

and calculating the actual offset like this

+ (CGFloat)offsetForAttributedString:(NSAttributedString *)attributedString drawRect:(CGRect)rect
{
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
    CFRange fullRange = CFRangeMake(0, [attributedString length]);
    CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, fullRange, path.CGPath, NULL);
    CFArrayRef lineArrayRef = CTFrameGetLines(frameRef);
    CFIndex lineCount = CFArrayGetCount(lineArrayRef);
    CGPoint lineOrigins[lineCount];
    CTFrameGetLineOrigins(frameRef, CFRangeMake(0, lineCount), lineOrigins);

    CGFloat offsetDueToLineHeight = 0.0;

    if(lineCount > 0)
    {
        CTLineRef firstLine = CFArrayGetValueAtIndex(lineArrayRef, 0);
        CGFloat ascent, descent, leading;
        CTLineGetTypographicBounds(firstLine, &ascent, &descent, &leading);
        offsetDueToLineHeight = rect.size.height - lineOrigins[0].y - ascent;
    }

    CFRelease(frameRef);
    CFRelease(framesetterRef);

    return offsetDueToLineHeight;
}

      



This value works for UITextDrawing

both Core Text

.

+1


source







All Articles