How to find actual number of lines of UILabel?

前端 未结 14 2240
灰色年华
灰色年华 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:40

    Swift 5 (IOS 12.2)

    Get max number of lines required for a label to render the text without truncation.

    extension UILabel {
        var maxNumberOfLines: Int {
            let maxSize = CGSize(width: frame.size.width, height: CGFloat(MAXFLOAT))
            let text = (self.text ?? "") as NSString
            let textHeight = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil).height
            let lineHeight = font.lineHeight
            return Int(ceil(textHeight / lineHeight))
        }
    }
    

    Get max number of lines can be displayed in a label with constrained bounds. Use this property after assigning text to label.

    extension UILabel {
        var numberOfVisibleLines: Int {
            let maxSize = CGSize(width: frame.size.width, height: CGFloat(MAXFLOAT))
            let textHeight = sizeThatFits(maxSize).height
            let lineHeight = font.lineHeight
            return Int(ceil(textHeight / lineHeight))
        }
    }
    

    Usage

    print(yourLabel.maxNumberOfLines)
    print(yourLabel.numberOfVisibleLines)
    
    0 讨论(0)
  • 2020-11-27 13:40
    let l = UILabel()
    l.numberOfLines = 0
    l.layer.frame.size.width = self.view.frame.width - 40 /*padding(20 + 20)*/
    
    l.font = UIFont(name: "BwModelica-Bold", size: 16.0)
    
    l.text = "Random Any length Text!!"
    
    let noOfLines = ceil(l.intrinsicContentSize.width) / l.frame.width)
    
    let lbl_height = noOfLines * l.intrinsicContentSize.height
    

    This will be your Exact dynamic height of Label and Number of lines. Happy coding!!!

    0 讨论(0)
  • 2020-11-27 13:44

    Here is the Swift3 Code here you can define Int value and get the height of text size by using (MAXFLOAT) and using that height you can get the total height of UILabel and by deviding that total height by character size you can get the actual line count of UILabel.

    var lineCount: Int = 0
    var textSize = CGSize(width: CGFloat(yourLabel.frame.size.width), height: CGFloat(MAXFLOAT))
    var rHeight: Int = lroundf(yourLabel.sizeThatFits(textSize).height)
    var charSize: Int = lroundf(yourLabel.font.leading)
    lineCount = rHeight / charSize
    print("No of lines: \(lineCount)")
    
    0 讨论(0)
  • 2020-11-27 13:48

    Xamarin.iOS

    Thanks to the answers everyone provided above.

    This gets number of visible lines.

    public static int VisibleLineCount(this UILabel label)
    {
        var textSize = new CGSize(label.Frame.Size.Width, nfloat.MaxValue);
        nfloat rHeight = label.SizeThatFits(textSize).Height;
        nfloat charSize = label.Font.LineHeight;
        return Convert.ToInt32(rHeight / charSize);
    }
    

    This gets actual number of lines the text will occupy on screen.

    public static int LineCount(this UILabel label)
    {
        var maxSize = new CGSize(label.Frame.Size.Width, nfloat.MaxValue);
        var charSize = label.Font.LineHeight;
        var text = (label.Text ?? "").ToNSString();
        var textSize = text.GetBoundingRect(maxSize, NSStringDrawingOptions.UsesLineFragmentOrigin, new UIStringAttributes() { Font = label.Font }, null);
        return Convert.ToInt32(textSize.Height / charSize);
    }
    

    A helper method I find useful for my use case.

    public static bool IsTextTruncated(this UILabel label)
    {
        if (label.Lines == 0)
        {
            return false;
        }
        return (label.LineCount() > label.Lines);
     }
    

    To get a more accurate line count:

    • Use font.lineHeight instead of font.pointSize
    • round() the line count after division
    0 讨论(0)
  • 2020-11-27 13:49

    None of these worked for me. Below one did,

    Swift 4.2:

    extension UILabel {
        func calculateMaxLines() -> Int {
            let maxSize = CGSize(width: frame.size.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
        }    
    }
    

    Swift 4/4.1:

    extension UILabel {
    
        func calculateMaxLines() -> Int {
            let maxSize = CGSize(width: frame.size.width, height: CGFloat(Float.infinity))
            let charSize = font.lineHeight
            let text = (self.text ?? "") as NSString
            let textSize = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
            let linesRoundedUp = Int(ceil(textSize.height/charSize)) 
            return linesRoundedUp
        }
    
    }
    

    Swift 3:

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

    Following up on @Prince's answer, I now implemented a category on UILabel as follows (note that I corrected some minor syntax mistakes in his answer that wouldn't let the code compile):

    UILabel+Util.h

    #import <UIKit/UIKit.h>
    
    @interface UILabel (Util)
    - (NSInteger)lineCount;
    @end
    

    UILabel+Util.,

    #import "UILabel+Util.h"
    
    @implementation UILabel (Util)
    
    - (NSInteger)lineCount
    {
        // Calculate height text according to font
        NSInteger lineCount = 0;
        CGSize labelSize = (CGSize){self.frame.size.width, FLT_MAX};
        CGRect requiredSize = [self.text boundingRectWithSize:labelSize  options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.font} context:nil];
    
        // Calculate number of lines
        int charSize = self.font.leading;
        int rHeight = requiredSize.size.height;
        lineCount = rHeight/charSize;
    
        return lineCount;
    }
    
    @end
    
    0 讨论(0)
提交回复
热议问题