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

Posted

技术标签:

【中文标题】使用 lineHeightMultiple 控制行间行距时,如何在 UITableViewCell 中垂直对齐我的 UILabel?【英文标题】:How do I vertically align my UILabel within a UITableViewCell, when using lineHeightMultiple to control leading between lines? 【发布时间】:2013-01-11 12:55:18 【问题描述】:

我在 UITableViewCell 中有一个多行 UILabel。我想控制线条之间的间距,将线条压缩得更近一些。我读过控制“领先”的唯一方法是使用属性字符串。所以我通过使标签属性而不是纯文本来做到这一点,然后我将 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 在每行中都比应有的更高,并且不再与右侧的箭头指示器垂直对齐。

【问题讨论】:

我认为当你将它添加到 UITableViewCell 时增加 UILable 的 y 位置可以让你的工作完成,这是我想出来的最简单的方法。许多其他选项也可用。 @Yuvrajsinh,如果你把它放在答案中,我会投票支持你的赏金答案。也可以调整 lineSpacing、paragraphSpacingBefore 和 paragraphSpacing 属性而不是这样做,以使文本在 UILabel 文本区域的中间按需要显示。 新的答案应该被接受为正确的答案,你不觉得吗? @hfossli 这听起来像是更好的解决方案,这就是我标记它的原因,但我还没有机会在我的代码中测试它,这就是我没有标记的原因它作为解决方案呢。 :) @MasonG.Zhwiti 有道理:) 【参考方案1】:

行高倍数会更改所有行的行高,包括第一行,因此它在您的标签中都会有点高。你真正想要的是调整行距,所以第二行的起始基线比默认值更近一点。

尝试替换:

paragraphStyle.lineHeightMultiple = 0.7;

与:

paragraphStyle.lineSpacing = -5.0;

根据口味调整行距值。

【讨论】:

谢谢!我发誓我尝试用 lineSpacing 代替 lineHeightMultiple,但永远无法让它正常工作(我想我可能是在尝试正整数而不是负整数)! 不确定这个解决方案是不是个好主意。来自 NSMutableParagraphStyle 接口:"@property(readonly) CGFloat lineSpacing; /* "Leading": 一个行片段的底部和下一个片段顶部之间的距离(应用于同一容器中的行之间)。不能为负。此值为包含在布局管理器的行片段高度中。*/" (由于设置任意值而被否决并不总是有帮助) 我很确定 lineSpacing 的负值是不行的。【参考方案2】:

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

【讨论】:

以上是关于使用 lineHeightMultiple 控制行间行距时,如何在 UITableViewCell 中垂直对齐我的 UILabel?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用命令行界面(CLI)重命名 laravel 控制器?

我需要使用从控制器获得的行变量,使用 Ajax 将其发送回另一个控制器

表视图侧视图控制器中的当前选定行

mac下使用mysql控制台命令行

Symfony2 通过命令行调用控制器

使用特定的发布配置文件通过命令行发布控制台应用程序