关于UILabel计算文字内容行数的简单实现

项目中遇到一个判断文字内容长度的需求,当以感觉有点麻烦,结果在吃饭的路上灵感闪现了一个办法,感觉回到电脑上实践,感觉有点靠谱,先记录下来,供日后备查之用.

整体的想法是这样的:

  • 不论文字内容有多长(为空的情况除外,另作判断即可),都先当作一行来处理,计算一下文本的size.
  • 再根据文字的实际内容,在限定宽度(一般计算行数都是宽带给定的)情况下,计算一下绘制文本的size.
  • 最后根据小学的数据基础,用实际的size高度除以单行size的高度,即可获得所需的行数.

代码实践

  • 获取文本单行size的方法

    1
    - (CGSize)sizeWithAttributes:(NSDictionary *)attrs NS_AVAILABLE_IOS(7_0);

使用方法

1
NSString *testString = @"我要测试一下文字内容的长度哦,不要一定非常准确,但是也可能非常正确,我就是用来测试文字行数才弄这么多字数在这里,呵呵,赶紧运行看看结果吧,不过你要记录一下单行计算下的size数值,后面会用来做比对的.";
// 计算一下14号字体的情况下,size的结果
CGSize size =[testString sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]}];
  • 获取多行文字size的方法

  • 1
    - (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(7_0);

使用方法

1
CGSize titleSize = [testString boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil].size;
  • 根据两次的获取结果,计算文本行数

    1
    int numberOfLine = ceil(titleSize.height / size.height);

添加到分类

在项目中可能会经常用到这种判断,因此写成一个UILabel的分类,专门用来判断内容的行数,

UILabel+Number.h

1
//
//  UILabel+Number.h
//  LoginDemo
//
//  Created by Alexcai on 15/7/15.
//  Copyright (c) 2015年 zhidier. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UILabel (Number)
/**
 *  获取Label文字内容的行数
 *
 *  @return 返回行数
 */
 - (CGFloat)numberOfText;
@end

UILabel+Number.m

1
//
//  UILabel+Number.m
//  LoginDemo
//
//  Created by Alexcai on 15/7/15.
//  Copyright (c) 2015年 zhidier. All rights reserved.
//

#import "UILabel+Number.h"

@implementation UILabel (Number)

- (CGFloat)numberOfText{
    // 获取单行时候的内容的size
    CGSize singleSize = [self.text sizeWithAttributes:@{NSFontAttributeName:self.font}];
    // 获取多行时候,文字的size
    CGSize textSize = [self.text boundingRectWithSize:CGSizeMake(self.frame.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.font} context:nil].size;
    // 返回计算的行数
    return ceil( textSize.height / singleSize.height);
}
@end

补充

关于boundingRectWithSize:option:attributes:context:方法中的option参数略解:

option参数是个枚举类型,一共有四个取值,说明如下:

  • NSStringDrawingTruncatesLastVisibleLine= 1 << 5,

    如果option参数为NSStringDrawingTruncatesLastVisibleLine,那么文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果指定了NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略

  • NSStringDrawingUsesLineFragmentOrigin= 1 << 0,

如果options参数为NSStringDrawingUsesLineFragmentOrigin,那么整个文本将以每行组成的矩形为单位计算整个文本的尺寸。

  • NSStringDrawingUsesFontLeading= 1 << 1,

如果option的参数为NSStringDrawingUsesFontLeading,那么计算文本行高时,使用行距

  • NSStringDrawingUsesDeviceMetrics= 1 << 3,

如果option的参数为NSStringDrawingUsesDeviceMetrics,那么计算布局时使用图元字形(而不是印刷字体)。

  • 因为这四个枚举类型使用了位移操作表示,我们可以使用或运算将多个参数组合在实际需求中.