如何findUILabel的行数

我使用wrap方法在UILabel中显示文本。 现在我想要findUILabel中有多less行。

如果有任何可能的方法来findUILabel的行数。

谢谢。

正如指出的,这篇文章涉及如何获得高度,而不是行数。 为了获得行数,

  1. 获得单个字母的高度,例如@"A"
  2. 将string的高度除以上面1中得到的高度。

例如

 CGFloat unitHeight = [@"A" heightForWidth:width usingFont:font]; CGFloat blockHeight = [text heightForWidth:width usingFont:font]; NSInteger numberOfLines = ceilf(blockHeight / unitHeight); // need to #include <math.h> for ^^^^^ 

从iOS 7开始,获得标签所需高度的方式发生了变化。 为了获得高度,你可以使用下面的代码:

 NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init]; CGSize labelSize = (CGSize){width, FLT_MAX}; CGRect r = [self boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:context]; 

高度是r.size.height 。 请注意,必须提供font 。 为了方便起见,你可以把它放到NSString的类中,例如

 @implementation NSString (HeightCalc) - (CGFloat)heightForWidth:(CGFloat)width usingFont:(UIFont *)font { NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init]; CGSize labelSize = (CGSize){width, FLT_MAX}; CGRect r = [self boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:context]; return r.size.height; } @end 

(做内存pipe理,如果不使用ARC,顺便说一句)。

对于iOS 6及以下版本:

比方说,你有一个UILabel *myLabel ,你想要找出标签的高度(通过一些调整,可以通过将高度除以取决于字体大小的适当数字来获得线的数量)。

 UILabel *myLabel; CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font constrainedToSize:myLabel.frame.size lineBreakMode:UILineBreakModeWordWrap]; CGFloat labelHeight = labelSize.height; 

希望有所帮助。 如果它不起作用,让我知道,我会进一步挖掘。 另外,未经testing的代码,但从参考工作。

对于一个更完整的例子,这里是我放在视图控制器的viewDidLoad:方法中的代码:

 [super viewDidLoad]; UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,50,200,350)]; myLabel.numberOfLines = 0; myLabel.lineBreakMode = UILineBreakModeWordWrap; myLabel.text = @"This is some text in a UILabel which is long enough to wrap around the lines in said UILabel. This is a test, this is only a test."; [self.view addSubview:myLabel]; CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font constrainedToSize:myLabel.frame.size lineBreakMode:UILineBreakModeWordWrap]; CGFloat labelHeight = labelSize.height; NSLog(@"labelHeight = %f", labelHeight); [myLabel release]; 

NSLog的输出结果如下:

 2010-11-15 18:25:27.817 so_labelheight[728:307] labelHeight = 126.000000 

对于iOS7及以上版本, 官方认可的计算行数的方法是使用TextKit:

 func numberOfLinesForString(string: String, size: CGSize, font: UIFont) -> Int { let textStorage = NSTextStorage(string: string, attributes: [NSFontAttributeName: font]) let textContainer = NSTextContainer(size: size) textContainer.lineBreakMode = .ByWordWrapping textContainer.maximumNumberOfLines = 0 textContainer.lineFragmentPadding = 0 let layoutManager = NSLayoutManager() layoutManager.textStorage = textStorage layoutManager.addTextContainer(textContainer) var numberOfLines = 0 var index = 0 var lineRange : NSRange = NSMakeRange(0, 0) for (; index < layoutManager.numberOfGlyphs; numberOfLines++) { layoutManager.lineFragmentRectForGlyphAtIndex(index, effectiveRange: &lineRange) index = NSMaxRange(lineRange) } return numberOfLines } 

现在不build议使用-sizeWithFont:constrainedToSize:lineBreakMode方法。 您将要使用方法-boundingRectWithSize:options:attributes:context: now。

这里有一个例子:

 CGSize boundingRectSize = CGSizeMake(widthToConstrainTo, CGFLOAT_MAX); NSDictionary *attributes = @{NSFontAttributeName : [UIFont fontWithName:fontName size:14]}; CGRect labelSize = [labelString boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil]; 

在上面的例子中,我知道我想限制标签的宽度,但是因为我不确定高度,所以我只是使用CGFLOAT_MAXCGFLOAT_MAX高度参数。 对于需要使用NSStringDrawingUsesLineFragmentOriginNSStringDrawingUsesFontLeadingoptions ,如果你想要计算大小的标签可以是任意数量的行。

sizeWithFont在iOS 7中已被弃用,您可以改为使用它:

 - (int)lineCountForText:(NSString *) text { UIFont *font = ... CGRect rect = [text boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil]; return ceil(rect.size.height / font.lineHeight); } 

如果你正在Swift 2 + / iOS 8中寻找这个答案,它会看起来像这样:

 func numberOfLinesInLabel(yourString: String, labelWidth: CGFloat, labelHeight: CGFloat, font: UIFont) -> Int { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = labelHeight paragraphStyle.maximumLineHeight = labelHeight paragraphStyle.lineBreakMode = .ByWordWrapping let attributes: [String: AnyObject] = [NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle] let constrain = CGSizeMake(labelWidth, CGFloat(Float.infinity)) let size = yourString.sizeWithAttributes(attributes) let stringWidth = size.width let numberOfLines = ceil(Double(stringWidth/constrain.width)) return Int(numberOfLines) } 

(我最初在这里发布了我的答案,但没有足够的评论或重复的声誉。)

我发现的其他答案并不尊重UILabelnumberOfLines属性,当它被设置为0以外的东西。

这是另一个可以添加到您的类别或子类的选项:

 - (NSUInteger)lineCount { CGSize size = [self sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)]; return MAX((int)(size.height / self.font.lineHeight), 0); } 

一些说明:

  • 我使用这个UILabel与归属文本,没有实际设置font属性,它工作正常。 显然,如果您在attributedText文本中使用多种字体,则会遇到问题。
  • 如果你将UILabel为自定义的边缘插入(例如,通过重写drawTextInRect:这是我在这里find的一个巧妙的技巧),那么当计算上面的size时,你必须记得考虑这些插入。 例如: CGSizeMake(self.frame.size.width - (self.insets.left + self.insets.right), CGFLOAT_MAX)
 func getHeight(text: NSString, width:CGFloat, font: UIFont) -> CGFloat { let rect = text.boundingRect(with: CGSize.init(width: width, height: CGFloat.greatestFiniteMagnitude), options: ([NSStringDrawingOptions.usesLineFragmentOrigin,NSStringDrawingOptions.usesFontLeading]), attributes: [NSFontAttributeName:font], context: nil) return rect.size.height } 

文本:标签的高度,你需要find给定的string

宽度:UILabel的宽度

字体:UILabel的字体