Iphone 如何找到UILabel';s行数

Iphone 如何找到UILabel';s行数,iphone,Iphone,我使用wrap方法在UILabel中显示文本。 现在我想知道UILabel中有多少行 如果有任何可能的方法可以找到UILabel的行数计数 谢谢。正如前面指出的,这篇文章讲述了如何获得高度,而不是行数。要获取行数 获取单个字母的高度,例如@“a” 将字符串的高度除以上面1中获得的高度 例如 其中高度为r.size.height。请注意,必须提供font。为了方便起见,您可以将其放入NSString的类别中,例如 @implementation NSString (HeightCalc) - (

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

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


谢谢。

正如前面指出的,这篇文章讲述了如何获得高度,而不是行数。要获取行数

  • 获取单个字母的高度,例如
    @“a”
  • 将字符串的高度除以上面1中获得的高度
  • 例如

    其中高度为
    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
    ,您想知道标签的高度(通过一些调整,您可以通过将高度除以一些适当的数字(取决于字体大小),得到行数)

    希望有帮助。如果它不起作用,让我知道,我会进一步挖掘。还有,未经测试的代码,但通过引用工作

    对于更完整的示例,下面是我放在视图控制器的viewDidLoad:method中的代码:

    [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
    

    现在不推荐使用
    -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\u max
    将高度参数设为最大值。对于
    选项
    ,如果您试图计算任意行数的标签大小,则需要使用
    nsStringDrawingUserLineFragmentOrigin
    nsStringDrawingUserFontLeading

    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);
    }
    
    对于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
    }
    
    func numberOfLinesForString(string:string,size:CGSize,font:UIFont)->Int{
    让textStorage=NSTextStorage(字符串:字符串,属性:[NSFontAttributeName:font])
    让textContainer=NSTextContainer(大小:size)
    textContainer.lineBreakMode=.ByWordWrapping
    textContainer.maximumNumberOfLines=0
    textContainer.lineFragmentPadding=0
    让layoutManager=NSLayoutManager()
    layoutManager.textStorage=textStorage
    layoutManager.addTextContainer(textContainer)
    var numberOfLines=0
    var指数=0
    变量lineRange:NSRange=NSMakeRange(0,0)
    对于(;索引
    (我最初发布了我的答案,但没有足够的声誉来评论或标记重复的答案。)

    我发现的其他答案不符合
    UILabel
    numberOfLines
    属性,当它设置为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:
      ,这是我发现的一个巧妙技巧),那么在计算上述
      大小时,必须记住将这些插入考虑在内。例如:
      CGSizeMake(self.frame.size.width-(self.insets.left+self.insets.right),CGFLOAT\u MAX)

    如果您要在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)
    }
    
    text:需要使用给定字符串查找其高度的标签

    宽度:UILabel的宽度


    font:UILabel的font

    它显示以下两个错误//错误:“sizeWithFont:constrainedToSize:lineBreakMode”的参数2的类型不兼容:“错误:请求非结构或UnionOf中的成员“大小”。大小不是UILabel上的属性,但它可能应该是类似于myLabel.frame.size或myLabel.bounds.size(不确定您想要哪个)。啊,是的,错过了那个。感谢Wim H。修复了上面的例子,使用frame.size。只是一个建议:与其使用
    (CGSize){width,999}
    ,不如使用
    (CGSize){width,FLT_MAX}
    ,这样就可以清楚这个数字的来源。这是回答问题的好方法,但实际上并没有回答前面提到的问题。问题是关于行数。考虑到这一点,你能更新你的答案吗?谢谢@AvielGross。编辑以反映您的输入。此处“约束”的目的是什么?这通常非常有效,但当textContainer具有
    lineBreakMode=.byWordWrapping
    时,行尾可以有无限数量的空格(位于容器外部),但是没有换行,也不会计算额外的换行。有什么办法可以防止吗?
    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
    }
    
    - (NSUInteger)lineCount
    {
        CGSize size = [self sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)];
        return MAX((int)(size.height / self.font.lineHeight), 0);
    }
    
    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)
    }
    
    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
    }