当使用lineHeightMultiple控制行之间的引导时,如何在UITableViewCell中垂直对齐我的UILabel?

时间:2013-01-28 07:58:19

标签: ios uitableview uilabel vertical-alignment nsattributedstring

我在UITableViewCell中有一个多行UILabel。我想控制线之间的间距,将线压缩得更近。我已经读过,控制“领先”的唯一方法是使用Attributed Strings。所以我通过使标签归属而不是纯文本来完成此操作,然后将lineHeightMultiple设置为0.7以压缩行:

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];

问题是,现在整个标签没有在UITableViewCell中垂直居中。

我该如何解决这个问题?在下面的附件中,您可以看到我的意思。 “压缩”多线UILabel在每行中的位置比它应该更高,并且不再与右侧的箭头指示器垂直对齐。

example

2 个答案:

答案 0 :(得分:2)

行高多次更改所有行的行高,包括第一行,因此它们在标签中都有一点高。你真正想要的是调整行间距,所以第二行的起始基线比默认值稍微靠近。

尝试更换:

paragraphStyle.lineHeightMultiple = 0.7;

使用:

paragraphStyle.lineSpacing = -5.0;

调整行间距值以便尝试。

答案 1 :(得分:1)

UITextDrawingCore Text都是这样做的。我认为这是超级变换..而不是使用lineSpacing的任意值 - 我说用Core Text计算这个并找出像这样的实际偏移量

+ (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;
}

此值适用于UITextDrawingCore Text