Ios 使用lineHeightMultiple控制行间的引线时,如何在UITableViewCell内垂直对齐UILabel?
我在UITableViewCell中有一个多行UILabel。我想控制线之间的间距,把线压缩得更近一点。我已经读到控制“前导”的唯一方法是使用属性字符串。因此,我通过将标签属性化而不是纯文本来实现这一点,然后将lineHeightMultiple设置为0.7以压缩行: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
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;
}