Ios 使用lineHeightMultiple控制行间的引线时,如何在UITableViewCell内垂直对齐UILabel?

Ios 使用lineHeightMultiple控制行间的引线时,如何在UITableViewCell内垂直对齐UILabel?,ios,uitableview,uilabel,vertical-alignment,nsattributedstring,Ios,Uitableview,Uilabel,Vertical Alignment,Nsattributedstring,我在UITableViewCell中有一个多行UILabel。我想控制线之间的间距,把线压缩得更近一点。我已经读到控制“前导”的唯一方法是使用属性字符串。因此,我通过将标签属性化而不是纯文本来实现这一点,然后将lineHeightMultiple设置为0.7以压缩行: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineHeightMultiple

我在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在每行中的位置都比它应该的位置高,并且不再与右侧的箭头指示器垂直对齐


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

尝试替换:

paragraphStyle.lineHeightMultiple = 0.7;
与:


调整行距值以适应口味。

这两个
UITextDrawing
核心文本
都可以执行此操作。我想这是超级市场。。不要对
行间距使用任意值,我说用
核心文本计算它,然后像这样算出实际偏移量

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

该值适用于
UITextDrawing
Core Text

我认为在将uitable添加到UITableViewCell时增加uitable的y位置可以完成工作,这是我想到的最简单的方法。还有很多其他选择。@Yuvrajsinh,如果你把悬赏的答案放在答案中,我会投你的票。也可以调整行扫描、段落间隔和段落间距属性,而不是这样做,以便文本在UIABEL文本区域的中间出现。新的答案应该被接受为正确的一个,你不觉得吗?@ HFSLII听起来像是更好的解决方案,这就是为什么我标记了它,但我还没有机会在代码中测试它,这就是为什么我还没有将它标记为解决方案的原因。:)@正威提说得通:)谢谢!我发誓我试过用线间距代替线高倍数,但始终无法让它正常工作(我想我可能是在尝试正整数而不是负整数)!我不确定这个解决方案是不是一个好主意。从NSMutableParagraphStyle界面:“@property(readonly)CGFloat lineSpacing;”/*“Leading”:一个线段底部和下一个线段顶部之间的距离(应用于同一容器中的两行之间)。不能为负值。此值包含在布局管理器中的线段高度中。*/”(由于设置任意值而被否决并不总是有帮助)我非常确定线宽的负值是不可能的。
+ (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;
}