计算UILabel文本大小

我以编程方式绘制UILabels 。 他们从数据库中获得他们的大小。 所以我不能只使用sizeToFit 。 我已经实现了一个函数,重绘UILabels与通过比例。 所以我需要find的是从我的看法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 

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

所有的[NSString sizeWithFont...]方法在iOS 7中都被弃用了。

 CGRect labelRect = [text boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:14] } context:nil]; 

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

更新 – boundingRectWithSize输出的例子

根据你的评论,我做了一个简单的testing。 代码和输出如下。

 // 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 = (%fx %f)", fontSize, r.size.width, r.size.height); } 

这会产生以下输出(请注意随着字体大小的变大,边界会发生变化):

 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) 

长度获取字符的数量。 如果你想获得文本的宽度:

Objective-C的

 CGSize textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[label font]}]; 

斯威夫特4

 let size = label.text?.size(withAttributes: [.font: label.font]) ?? .zero 

这让你的大小。 你可以比较每个标签的textSize.width

另一个简单的方法来做到这一点,我还没有看到提到:

 CGSize textSize = [label intrinsicContentSize]; 

(当然,当你设置标签的文本和字体后,这只能正常工作。)

这是一个迅速的变种。

 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) 

小build议家伙,如果像我一样,你正在使用boundingRectWithSize[UIFont systemFontOFSize:14]

如果你的string是两行,返回的矩形高度就是33,4点。

不要把错误和我一样,把它变成一个int ,因为33,4变成了33,并且33点的高度标签从两行传到一行!

与的问题

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

boundingRectWithSize ,它决定了CGRect可以拥有的最大值。

我对这个问题的解决scheme是检查是否超出,如果不是,那么文本可以适应标签。 我通过使用循环做到了。

 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 = (%fx %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); 

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

我select6的原因是因为我不希望标签太混乱。

对于不使用循环的解决scheme:

 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 = (%fx %f) = %f", fontSize, r.size.width, r.size.height,r.size.width*r.size.height); firstVal =r.size.width*r.size.height; } 

最后一个循环certificate更大的字体可以提供更高的结果。

通过使用这一行代码,我们可以得到标签上文本的大小。

 let str = "Sample text" let size = str.sizeWithAttributes([NSFontAttributeName:UIFont.systemFontOfSize(17.0)]) 

所以,我们可以使用宽度和高度。

msgStrstring获取大小:

 let msgStr:NSString = Data["msg"]! as NSString let messageSize = msgStr.boundingRect(with: CGSize(width: ChatTable.frame.width-116, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont(name: "Montserrat-Light", size: 14)!], context: nil).size