计算UILabel文本大小

Sar*_*aya 54 objective-c frame uilabel ios

我是以UILabels编程方式绘制的.他们从数据库中获取大小.所以我不能只使用sizeToFit.我已经实现了UILabels一个以传递比率重绘的函数.所以我需要找到的是UILabel我视图中的文本,需要重新绘制最大比例UILabels.所以最后我需要做这样的事情:

    double ratio = 1.00;
    for (UILabel* labels in sec.subviews) {

        float widthLabel = labels.frame.size.width;
        float heightLabel = labels.frame.size.height;
        float heightText = //get the text height here
        float widthText = //get the text width here
        if (widthLabel < widthText) {
            ratio = MAX(widthText/widthLabel,ratio);
        }
        if (heightLabel < heightText) {
            ratio = MAX(heightText/heightLabel, ratio);
        }
    }
    //redraw UILabels with the given ratio here
Run Code Online (Sandbox Code Playgroud)

那么如何获得文本的高度和宽度大小,因为我的一些文本不适合标签我不能简单地使用标签边界?我正在使用Xcode 5和iOS 7.

XJo*_*nes 66

[NSString sizeWithFont...]iOS 7中不推荐使用所有方法.请改用此方法.

CGRect labelRect = [text
                    boundingRectWithSize:labelSize
                    options:NSStringDrawingUsesLineFragmentOrigin
                    attributes:@{
                     NSFontAttributeName : [UIFont systemFontOfSize:14]
                    }
                    context:nil];
Run Code Online (Sandbox Code Playgroud)

另请参阅https://developer.apple.com/documentation/foundation/nsstring/1619914-sizewithfont.

UPDATE - boundingRectWithSize输出的示例

根据你的评论我做了一个简单的测试.代码和输出如下.

// code to generate a bounding rect for text at various font sizes
NSString *text = @"This is a long sentence. Wonder how much space is needed?";
for (NSNumber *n in @[@(12.0f), @(14.0f), @(18.0f)]) {
    CGFloat fontSize = [n floatValue];
    CGRect r = [text boundingRectWithSize:CGSizeMake(200, 0)
                                  options:NSStringDrawingUsesLineFragmentOrigin
                               attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
                                  context:nil];
    NSLog(@"fontSize = %f\tbounds = (%f x %f)",
          fontSize,
          r.size.width,
          r.size.height);
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出(请注意,当字体大小变大时,边界会按预期更改):

fontSize = 12.000000    bounds = (181.152008 x 28.632000)
fontSize = 14.000000    bounds = (182.251999 x 50.105999)
fontSize = 18.000000    bounds = (194.039993 x 64.421997)
Run Code Online (Sandbox Code Playgroud)


H. *_*nar 50

长度获取字符数.如果要获取文本的宽度:

Objective-C的

CGSize textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[label font]}];
Run Code Online (Sandbox Code Playgroud)

斯威夫特4

let size = label.text?.size(withAttributes: [.font: label.font]) ?? .zero
Run Code Online (Sandbox Code Playgroud)

这可以帮助你达到规模.你可以比较textSize.width每个标签.

  • 请注意,这不适用于多行UILabel (4认同)
  • 这应该是最好的答案. (2认同)

pof*_*off 26

另一个我还没有提到的简单方法:

CGSize textSize = [label intrinsicContentSize];
Run Code Online (Sandbox Code Playgroud)

(当然,只有在设置了标签的文本和字体后才能正常工作.)

  • 这对我来说是正确的答案.boundingRectWithSize有时会提供不正确的大小. (2认同)

Col*_*lin 17

这是一个迅速的变种.

let font = UIFont(name: "HelveticaNeue", size: 25)!
let text = "This is some really long text just to test how it works for calculating heights in swift of string sizes. What if I add a couple lines of text?"

let textString = text as NSString

let textAttributes = [NSFontAttributeName: font]

textString.boundingRectWithSize(CGSizeMake(320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil)
Run Code Online (Sandbox Code Playgroud)


Sar*_*aya 2

问题在于

CGRect r = [text boundingRectWithSize:CGSizeMake(200, 0)
                              options:NSStringDrawingUsesLineFragmentOrigin
                           attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
                              context:nil];
Run Code Online (Sandbox Code Playgroud)

boundingRectWithSize决定 CGRect 可以具有的最大值。

我对这个问题的解决方案是检查它是否超过,如果没有,则文本可以适合标签。我是通过使用循环来完成的。

NSString *text = @"This is a long sentence. Wonder how much space is needed?";
CGFloat width = 100;
CGFloat height = 100;
bool sizeFound = false;
while (!sizeFound) {
    NSLog(@"Begin loop");
    CGFloat fontSize = 14;
    CGFloat previousSize = 0.0;
    CGFloat currSize = 0.0;
    for (float fSize = fontSize; fSize < fontSize+6; fSize++) {
        CGRect r = [text boundingRectWithSize:CGSizeMake(width, height)
                                      options:NSStringDrawingUsesLineFragmentOrigin
                                   attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fSize]}
                                      context:nil];
        currSize =r.size.width*r.size.height;
        if (previousSize >= currSize) {
            width = width*11/10;
            height = height*11/10;
            fSize = fontSize+10;
        }
        else {
            previousSize = currSize;
        }
        NSLog(@"fontSize = %f\tbounds = (%f x %f) = %f",
              fSize,
              r.size.width,
              r.size.height,r.size.width*r.size.height);
    }
    if (previousSize == currSize) {
        sizeFound = true;
    }

}
NSLog(@"Size found with width %f and height %f", width, height);
Run Code Online (Sandbox Code Playgroud)

每次迭代后,高度和宽度的大小都会增加其值的 10%。

我之所以选择6是因为我不想让标签太软。

对于不使用循环的解决方案:

NSString *text = @"This is a long sentence. Wonder how much space is needed?";
CGFloat width = 100;
CGFloat height = 100;

CGFloat currentFontSize = 12;
CGRect r1 = [text boundingRectWithSize:CGSizeMake(width, height)
                              options:NSStringDrawingUsesLineFragmentOrigin
                           attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize+6]}
                              context:nil];

CGRect r2 = [text boundingRectWithSize:CGSizeMake(width, height)
                               options:NSStringDrawingUsesFontLeading
                            attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize+6]}
                               context:nil];

CGFloat firstVal =r1.size.width*r1.size.height;
CGFloat secondVal =r2.size.width*r2.size.height;

NSLog(@"First val %f and second val is %f", firstVal, secondVal);

if (secondVal > firstVal) {
    float initRat = secondVal/firstVal;

    float ratioToBeMult = sqrtf(initRat);

    width *= ratioToBeMult;
    height *= ratioToBeMult;
}

NSLog(@"Final width %f and height %f", width, height);

//for verifying
for (NSNumber *n in @[@(12.0f), @(14.0f), @(17.0f)]) {
    CGFloat fontSize = [n floatValue];
    CGRect r = [text boundingRectWithSize:CGSizeMake(width, height)
                                  options:NSStringDrawingUsesLineFragmentOrigin
                               attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
                                  context:nil];
    NSLog(@"fontSize = %f\tbounds = (%f x %f) = %f",
          fontSize,
          r.size.width,
          r.size.height,r.size.width*r.size.height);
    firstVal =r.size.width*r.size.height;
}
Run Code Online (Sandbox Code Playgroud)

最后一个循环证明较大的字体可以提供更大的结果。