26
2017
09

iOS 关于UILabel文本的自适应

以下根据具体情况举例说明演示

// 例子文本
NSArray *contents = @[
                    @"人生若只如初见,何事秋风悲画扇!",
                    @"sjkf基地哦激发我 i 肌肤 i 哦文件软件 啊数据分类健身房逻辑啊谁来减肥减父爱数据佛 i 为 i 即佛 i 的风景啊啥的减肥卡姐搜附近的减肥就啊苦尽甘来将阿拉大方接受逻辑法拉盛觉得饭卡老骥伏枥科技馆 i 哦额阿胶糕就就 看见饿了科技 呃呃呃 就 就发生减肥的卢卡斯了风景啊数据的 结尾 i 呃减肥的风景咖色九分裤 减肥 i 哦少女尽快形成女奴诶混空间室内卡夫卡里嘎多 的飞机上的减肥空间啊是克己复礼撒娇的风景啊是关乎恶搞八廓街看风景啊可是发动机空间"
                      ];

单行文本

1、通过 text 字符串计算size

方法:

- (CGSize)sizeWithAttributes:(nullable NSDictionary<NSString *, id> *)attrs;

例子:

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.firstObject;
// 根据文本计算size,这里需要传入attributes
CGSize sizeNew = [self.contentLabel.text sizeWithAttributes:@{NSFontAttributeName:self.contentLabel.font}];
// 重新设置frame
self.contentLabel.frame = CGRectMake(0, 0, sizeNew.width, sizeNew.height);
// 输出此时控件的大小
NSLog(@"%@",NSStringFromCGSize(self.contentLabel.frame.size));
self.contentLabel.center = self.view.center;

输出的size

sizeWithAttributes

label的样式

样式

2、通过 attributedText 富文本直接计算size

方法:

- (CGSize)size;

例子:

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.firstObject;
// 计算文本size
CGSize sizeNew = [self.contentLabel.attributedText size];
self.contentLabel.frame = CGRectMake(0, 0, sizeNew.width, sizeNew.height);
// 输出此时控件的大小
NSLog(@"%@",NSStringFromCGSize(self.contentLabel.frame.size));
self.contentLabel.center = self.view.center;

此时的size

frame

label的样式

样式

3、通过UIView的 sizeThatFits

方法:

- (CGSize)sizeThatFits:(CGSize)size;

说明:返回“最佳”大小以适应给定大小。 默认是返回现有的视图大小

例子

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.firstObject;
self.contentLabel.numberOfLines = 1; // 指定为单行文本
CGSize newSize = [self.contentLabel sizeThatFits:CGSizeZero]; // 在单行文本的情况下,参数size设置多少都无所谓,所以里传了CGSizeZero
self.contentLabel.frame = CGRectMake(0, 0, newSize.width, newSize.height);
NSLog(@"%@",NSStringFromCGSize(self.contentLabel.frame.size));
self.contentLabel.center = self.view.center;

此时输出的size

frame

此时样式

样式

4、通过UIView的 sizeToFit

方法:

// 该方法调用了 sizeThatFits
- (void)sizeToFit;

例子

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.firstObject;
self.contentLabel.numberOfLines = 1;
// 调用 sizeToFit
[self.contentLabel sizeToFit];
NSLog(@"%@",NSStringFromCGSize(self.contentLabel.frame.size));
self.contentLabel.center = self.view.center;

此时输出的size

frame

此时样式

样式


总结:

1、1和2的方法是通过计算文本的size后重新设置frame来自适应,3和4则是利用了UIView视图的方法

2、在numberOfLines = 1,指定为单行的情况下,sizeThatFits 会自动计计算并返回最佳的size,而sizeToFit方法会在调用sizeThatFits的同时,重新设置label的size

补充

指定宽度适应文本的font

@property(nonatomic) BOOL adjustsFontSizeToFitWidth; 

说明:设置为YES,根据width自动调整字体的font


多行文本

1、通过 text 计算

方法:

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context

例子:

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.lastObject;
self.contentLabel.numberOfLines = 0;
// 根据指定width计算新的bounds
CGRect frameNew = [self.contentLabel.text boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width-10*2, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.contentLabel.font} context:nil]; // 指定为width,通常都是控件的width都是固定调整height
self.contentLabel.frame = frameNew; 
NSLog(@"%@",NSStringFromCGSize(frameNew.size));
self.contentLabel.center = self.view.center;

输出的size:

size

label样式:

样式

2、通过 attributedText 富文本直接计算size

如果label已经使用了富文本,也可以通过富文本计算size

方法:

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(nullable NSStringDrawingContext *)context;

说明:比起1,这个方法不需要再设置attributes

计算的size,lable样式都和1一样,就不贴图了

3、通过UIView的 sizeThatFits

方法:

- (CGSize)sizeThatFits:(CGSize)size;

例子:

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.lastObject;
self.contentLabel.numberOfLines = 0;
// 根据指定width计算size
CGSize newSize = [self.contentLabel sizeThatFits:CGSizeMake([UIScreen mainScreen].bounds.size.width-10*2, MAXFLOAT)];
self.contentLabel.frame = CGRectMake(0, 0, newSize.width, newSize.height);
NSLog(@"%@",NSStringFromCGSize(newSize));
self.contentLabel.center = self.view.center;

输出的size:

size

label样式:

样式

4、通过UIView的 sizeToFit

方法:

// 该方法调用了 sizeThatFits
- (void)sizeToFit;

例子:

self.contentLabel.font = [UIFont systemFontOfSize:20];
self.contentLabel.text = contents.lastObject;
self.contentLabel.numberOfLines = 0;
self.contentLabel.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width-10*2, MAXFLOAT);
// 计算size,sizeToFit会使用label的width来计算最佳的height
[self.contentLabel sizeToFit]; NSLog(@"%@",NSStringFromCGSize(self.contentLabel.frame.size));
self.contentLabel.center = self.view.center;

计算的size:

size


总结:

1、比起计算文本的size来自适应,系统提供的 sizeToFit 要方便很多,因为它不需要富文本参数来计算(设置起来也相当的麻烦),而直接通过控件本身属性计算size

2、通过计算文本来自适应会出现问题,在有些特殊情况下并不太准确,所以还是推荐使用sizeToFit

3、使用sizeToFit计算的size可能会改变最初的width,这是因为字符换行的问题,不过和设定的width相差不大


使用sizeToFit并不需要开发这考虑富文本设置问题,例如,富文本设置了行间距

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:10]; // 行间距为10
self.contentLabel.attributedText = [[NSAttributedString alloc] initWithString:contents.lastObject attributes:@{                                                                                                                 NSFontAttributeName:self.contentLabel.font,                                                                                                               NSForegroundColorAttributeName:[UIColor redColor],                                                                                                             NSParagraphStyleAttributeName:paragraphStyle                                                                                                               }];

计算出来的size:

size

样式:

样式


以上就是我总结的UILabel文本自适应总结,若有问题,欢迎大家留言讨论、学习

上一篇:安卓文件下载之断点续传(一) 下一篇:Android 8.0 功能和 API