平衡多线UILabel

时间:2014-10-23 14:23:00

标签: ios objective-c uilabel line-breaks

当我创建UILabel textAlignement设置为NSTextAlignmentCenterlineBreakMode设置为NSLineBreakByWordWrapping且文本为长文时,它会像这样分割:

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

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

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

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

4 个答案:

答案 0 :(得分:3)

我有同样的问题,受到这个问题的启发,我发现了一个解决方案,只是重写 - (void)drawTextInRect:(CGRect)rect

您可以在this GitHub Project

中看到它

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

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

PR,叉子,欢迎评论!

答案 1 :(得分:2)

我在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)
}

答案 2 :(得分:0)

您无需内置任何支持。您需要使用NSString boundingRectWithSize:options:attributes:context:进行自己的计算。您将需要循环各种尺寸以找到最佳宽度以获得两条实线。然后使用该宽度来调整UILabel的大小。

答案 3 :(得分:-1)

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