如何查找UILabel的实际行数?

nbu*_*urk 60 uilabel ios

在用a 和a 初始化之后,如何找到a的实际行数?我已将其属性设置为,因此它将扩展到需要许多行.但是,我如何才能找到它设置后最终获得了多少行?UILabeltextfontnumberOfLines0text

我发现了类似的问题,但似乎没有一个提供简洁的答案,在我看来,在没有任何开销的情况下得到它一定非常容易,boundingRectWithSize或者sizeWithFont......

Kur*_*t J 60

这些都不适合我.下面做了一个,

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
    }    
}
Run Code Online (Sandbox Code Playgroud)

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
    }

}
Run Code Online (Sandbox Code Playgroud)

斯威夫特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
    }

}
Run Code Online (Sandbox Code Playgroud)


Par*_*iya 50

首先在UILabel中设置文本

第一选择:

首先根据字体计算文本的高度:

NSInteger lineCount = 0;
CGSize labelSize = (CGSize){yourLabel.frame.size.width, MAXFLOAT};
CGRect requiredSize = [self boundingRectWithSize:labelSize  options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: yourLabel.font} context:nil];
Run Code Online (Sandbox Code Playgroud)

现在计算行数:

int charSize = lroundf(yourLabel.font.lineHeight);
int rHeight = lroundf(requiredSize.height);
lineCount = rHeight/charSize;
NSLog(@"No of lines: %i",lineCount);
Run Code Online (Sandbox Code Playgroud)

第二种选择:

 NSInteger lineCount = 0;
 CGSize textSize = CGSizeMake(yourLabel.frame.size.width, MAXFLOAT);
 int rHeight = lroundf([yourLabel sizeThatFits:textSize].height);
 int charSize = lroundf(yourLabel.font.lineHeight);
 lineCount = rHeight/charSize;
 NSLog(@"No of lines: %i",lineCount);
Run Code Online (Sandbox Code Playgroud)

  • int charSize = lroundf(yourLabel.font.lineHeight); (5认同)
  • 就像@BrooksHanes 提到的那样——行距与 lineHeight 不同是`前导值表示文本行之间的额外空间,以磅为单位。`(https://developer.apple.com/reference/uikit/uifont/ 1619026-领先)。 (2认同)
  • 这始终不会返回正确的值. (2认同)

ram*_*a n 42

Swift 3(IOS 10.3)

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))
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

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))
    }
}
Run Code Online (Sandbox Code Playgroud)

  • It gave one more line for me, number of visible lines was 5 but your method returned 6. (4认同)
  • `let zone = CGSize(width: internalContentSize.width, height: CGFloat(MAXFLOAT)) let fitingHeight = Float(self.sizeThatFits(zone).height) return lroundf(fittingHeight / Float(font.lineHeight))`计算出正确的线条为了我 (2认同)

dan*_*ner 16

这是@Paresh解决方案的快速版本:

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
}
Run Code Online (Sandbox Code Playgroud)

编辑:我不知道为什么,但代码返回的行多于实际行数,对于我的解决方案,我只是在返回lineCount之前减去它们.


pej*_*alo 10

这里的其他答案不尊重何时设置为0以外的numberOfLines属性UILabel.

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

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

一些说明:

  • 我在带有属性文本的UILabel上使用它,而没有实际设置font属性,并且它工作正常.显然,如果你在你的中使用多种字体,你会遇到问题attributedText.
  • 如果你是子类化UILabel有自定义边缘插入(例如通过覆盖drawTextInRect:,这是我在这里找到的一个巧妙的技巧),那么你必须记住在计算size上面时考虑这些插入.例如:CGSizeMake(self.frame.size.width - (self.insets.left + self.insets.right), CGFLOAT_MAX)


Fer*_*nas 10

斯威夫特 5.2

让它对我有用的要点是调用label.layoutIfNeeded()因为我使用的是autoLayout,否则它不起作用。

func actualNumberOfLines(label: UILabel) -> Int {
        // You have to call layoutIfNeeded() if you are using autoLayout
        label.layoutIfNeeded()

        let myText = label.text! as NSString

        let rect = CGSize(width: label.bounds.width, height: CGFloat.greatestFiniteMagnitude)
        let labelSize = myText.boundingRect(with: rect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: label.font as Any], context: nil)

        return Int(ceil(CGFloat(labelSize.height) / label.font.lineHeight))
    }
Run Code Online (Sandbox Code Playgroud)

归功于:https : //gist.github.com/fuxingloh/ccf26bb68f4b8e6cfd02,它在较旧的 swift 版本中提供了解决方案,并提到了 layoutIfNeeded() 的重要性。


Azh*_*ikh 8

这里是Swift3代码 ,您可以通过使用(MAXFLOAT)定义Int值并获取文本大小的高度,使用该高度可以获得UILabel的总高度,并通过字符大小来计算总高度,您可以获得实际行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)")
Run Code Online (Sandbox Code Playgroud)


nbu*_*urk 5

根据 @Prince 的回答,我现在实现了一个类别,如下UILabel所示(请注意,我纠正了他的回答中的一些小语​​法错误,这些错误不会让代码编译):

UILabel+Util.h

#import <UIKit/UIKit.h>

@interface UILabel (Util)
- (NSInteger)lineCount;
@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • Apple 文档中的“leading”内容为“改为使用“lineHeight”属性。” 事实上,在我的“UILabel”上,字体的“leading”属性等于 0。 (5认同)

Kau*_*iya 5

您可以在自定义标签中找到可用的总行数请检查此代码...

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);
}
Run Code Online (Sandbox Code Playgroud)


小智 5

官方开发者网站上似乎提到了一种解决方案Counting Lines of Text in Objc。但是,它假设您有对配置了布局管理器、文本存储和文本容器的文本视图的引用。不幸的是,UILabel 不会向我们公开这些,因此我们需要使用与 UILabel 相同的配置创建它们。

我将 Objc 代码翻译成 swift 如下。这对我来说似乎很有效。

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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 始终返回第 1 行的编号, (3认同)