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文本自适应总结,若有问题,欢迎大家留言讨论、学习

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容