How to find actual number of lines of UILabel?

前端 未结 14 2256
灰色年华
灰色年华 2020-11-27 13:10

How can I find the actual number of lines of a UILabel after I have initialized it with a text and a font? I have set

相关标签:
14条回答
  • 2020-11-27 13:51

    You can find the total number of line available in your custom label Please check this code...

    NSInteger numberOfLines = [self lineCountForText:@"YOUR TEXT"];
    
    - (int)lineCountForText:(NSString *) text
    {
        UIFont *font = [UIFont systemFontOfSize: 15.0];
        int width=Your_LabelWidht;
    
        CGRect rect = [text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin  attributes:@{NSFontAttributeName : font} context:nil];
        return ceil(rect.size.height / font.lineHeight);
    }
    
    0 讨论(0)
  • 2020-11-27 13:52

    Note that @kurt-j's answer will not always work. In some cases, you will have to manually provide the width of label. Since these cases exist, it is a good idea to have an optional width parameter, even if you don't end up using it.

    Swift 4.2:

    extension UILabel {
        func calculateMaxLines(actualWidth: CGFloat?) -> Int {
            var width = frame.size.width
            if let actualWidth = actualWidth {
                width = actualWidth
            }
            let maxSize = CGSize(width: width, height: CGFloat(Float.infinity))
            let charSize = font.lineHeight
            let text = (self.text ?? "") as NSString
            let textSize = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
            let linesRoundedUp = Int(ceil(textSize.height/charSize)) 
            return linesRoundedUp
        }    
    }
    
    0 讨论(0)
  • 2020-11-27 13:54

    It seems that the official developer website mentions one solution Counting Lines of Text in Objc. However, it assumes you have a reference to a text view configured with a layout manager, text storage, and text container. Unfortunately, UILabel doesn't expose those to us, so we need create them with the same configuration as the UILabel.

    I translated the Objc code to swift as following. It seems work well for me.

    extension UILabel {
        var actualNumberOfLines: Int {
            let textStorage = NSTextStorage(attributedString: self.attributedText!)
            let layoutManager = NSLayoutManager()
            textStorage.addLayoutManager(layoutManager)
            let textContainer = NSTextContainer(size: self.bounds.size)
            textContainer.lineFragmentPadding = 0
            textContainer.lineBreakMode = self.lineBreakMode
            layoutManager.addTextContainer(textContainer)
    
            let numberOfGlyphs = layoutManager.numberOfGlyphs
            var numberOfLines = 0, index = 0, lineRange = NSMakeRange(0, 1)
    
            while index < numberOfGlyphs {
                layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
                index = NSMaxRange(lineRange)
                numberOfLines += 1
            }
            return numberOfLines
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:00

    Xamarin iOS

    label.Text = text;
    
    var lineCount = 0;
    var textSize = new CGSize(label.Frame.Size.Width, float.MaxValue);
    var height = label.SizeThatFits(textSize).Height;
    var fontHeight = label.Font.LineHeight;
    
    lineCount = Convert.ToInt32(height / fontHeight);
    
    0 讨论(0)
  • 2020-11-27 14:02

    Here is a swift version of @Paresh solution:

    func lines(label: UILabel) -> Int {
        let textSize = CGSize(width: label.frame.size.width, height: CGFloat(Float.infinity))
        let rHeight = lroundf(Float(label.sizeThatFits(textSize).height))
        let charSize = lroundf(Float(label.font.lineHeight))
        let lineCount = rHeight/charSize
        return lineCount
    }
    

    EDIT: I don't know why, but the code is returning 2 more lines than the actual number of lines, for my solution, I just subtracted them before returning lineCount.

    0 讨论(0)
  • 2020-11-27 14:02

    The other answers here don't respect the numberOfLines property of UILabel when it is set to something other than 0.

    Here's another option you can add to your category or subclass:

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

    Some notes:

    • I'm using this on a UILabel with attributed text, without ever actually setting the font property, and it's working fine. Obviously you would run into issues if you were using multiple fonts in your attributedText.
    • If you are subclassing UILabel to have custom edge insets (for example by overriding drawTextInRect:, which is a neat trick I found here), then you must remember to take those insets into account when calculating the size above. For example: CGSizeMake(self.frame.size.width - (self.insets.left + self.insets.right), CGFLOAT_MAX)
    0 讨论(0)
提交回复
热议问题