平衡多行UILabel

当我创build一个NSLineBreakByWordWrappingNSTextAlignmentCenter设置为NSTextAlignmentCenterNSLineBreakByWordWrappingNSLineBreakByWordWrapping和一个长文本,它分裂如下:

 +------------------------------------+ | Text that does not fit on a single | | line | +------------------------------------+ 

但是我真正想要的是这样的:

 +------------------------------------+ | Text that does not fit | | on a single line | +------------------------------------+ 

当然,我不想手动处理换行符。 我希望标签自动平衡线条,使其长度尽可能接近。

我有同样的问题,并由这个问题的启发,我find了一个解决scheme,只是重写- (void)drawTextInRect:(CGRect)rect

你可以在这个GitHub项目中看到它

方法本身,如果你只是想复制/阅读它在这里

 - (void)drawTextInRect:(CGRect)rect { if (self.textAlignment == NSTextAlignmentCenter) { CGRect oneLineRect = [self textRectForBounds:CGRectInfinite limitedToNumberOfLines:1]; NSInteger numberOfLines = ceil(oneLineRect.size.width / self.bounds.size.width); CGFloat betterWidth = (oneLineRect.size.width / numberOfLines); if (betterWidth < rect.size.width) { CGRect check = CGRectZero; do { betterWidth *= 1.1; CGRect b = CGRectMake(0, 0, betterWidth, CGRectInfinite.size.height); check = [self textRectForBounds:b limitedToNumberOfLines:0]; } while (check.size.height > rect.size.height && betterWidth < rect.size.width); if (betterWidth < rect.size.width) { CGFloat difference = rect.size.width - betterWidth; rect = CGRectMake(rect.origin.x + difference/2.0, rect.origin.y, betterWidth, rect.size.height); } } } [super drawTextInRect:rect]; } 

公关,叉,欢迎评论!

我在Swift 3(iOS 10)中工作,所以我把dev_jac的答案转换成了需要它的人:

 override func drawText(in rect: CGRect) { var newRect = rect if (textAlignment == .center) { let oneLineRect = self.textRect(forBounds: CGRect.infinite, limitedToNumberOfLines: 1) let numLines = ceil(oneLineRect.size.width / self.bounds.size.width) var betterWidth : CGFloat = oneLineRect.size.width / numLines if (betterWidth < rect.size.width) { var check = CGRect.zero repeat { betterWidth *= 1.1 let b = CGRect(x: 0, y: 0, width: betterWidth, height: CGRect.infinite.size.height) check = self.textRect(forBounds: b, limitedToNumberOfLines: 0) } while (check.size.height > rect.size.height && betterWidth < rect.size.width) if betterWidth < rect.size.width { let difference : CGFloat = rect.size.width - betterWidth newRect = CGRect(x: rect.origin.x + difference/2, y: rect.origin.y, width: betterWidth, height: rect.size.height) } } } super.drawText(in: newRect) } 

没有内置的支持你需要的东西。 您将需要使用NSString boundingRectWithSize:options:attributes:context:来执行自己的计算。 你将需要循环通过各种尺寸来find最佳的宽度来获得两个实线。 然后使用该宽度来调整UILabel大小。

如果使用自动布局,则UILabel的 preferredMaxLayoutWidth属性可能对您有用。