如何找到UILabel的行数

时间:2010-11-13 12:58:22

标签: iphone

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

如果有任何可能的方法可以找到UILabel的行数。

感谢。

7 个答案:

答案 0 :(得分:50)

正如所指出的,这篇文章涉及如何获得高度,而不是线的数量。要获得行数,

  1. 获取单个字母的高度,例如@"A"
  2. 将字符串的高度除以上面1中获得的高度。
  3. E.g。

    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
    

    (如果不使用ARC,请进行内存管理,顺便说一句。)

    适用于iOS 6及以下版本:

    假设您有一个UILabel *myLabel,并且想要找出标签的高度(通过一些调整,您可以通过将高度除以一些适当的数字来获得行数,这取决于字体大小)。

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

    希望有所帮助。如果它不起作用,请告诉我,我会进一步挖掘。此外,未经测试的代码,但参考。

    有关更完整的示例,这里是我放在视图控制器的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
    

答案 1 :(得分:14)

对于iOS7及以上版本,计算行数的officially sanctioned way是使用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
}

答案 2 :(得分:7)

现在不推荐使用方法-sizeWithFont:constrainedToSize:lineBreakMode。您现在想要使用方法-boundingRectWithSize:options:attributes:context:

以下是一个例子:

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_MAX来最大化高度参数。对于options,您需要使用NSStringDrawingUsesLineFragmentOriginNSStringDrawingUsesFontLeading,如果您正在尝试计算可以是任意行数的标签大小。

答案 3 :(得分:6)

在iOS 7中不推荐使用

sizeWithFont,您可以改用它:

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

答案 4 :(得分:6)

如果你在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)
}

答案 5 :(得分:2)

(我最初发布了我的回答here,但没有足够的声誉来评论或标记重复项。)

我发现其他答案在numberOfLines设置为0以外的其他属性时不尊重UILabel属性。

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

- (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:,这是我找到here的一个巧妙的技巧,那么你必须记住采取这些插入在计算上面的size时会考虑到这一点。例如:CGSizeMake(self.frame.size.width - (self.insets.left + self.insets.right), CGFLOAT_MAX)

答案 6 :(得分:0)

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
}

text:您需要使用给定字符串找到其高度的标签

width:UILabel的宽度

font:UILabel的字体