前言:我们在做开发时,有时候lable的文字多少,并不是我们确定的,这个时候就需要lable的大小随文字的变化而变化。一般都是宽度固定,让高度发生变化。下面介绍几种方法,和其中有可能出现的问题。
注意:使用文字自适应的方法:首先设置frame大小,在赋值文字,最后在自适应,顺序不要写错,不然可能自适应无效。原理:自适应是根据文字多少来变化的,如果不先赋值文字,默认就是0个文字,高度自然不会变化
sizeToFit会自动根据文字的多少来改变宽度和高度,需要注意的是:在初始化lable时,需要先设置frame大小。然后赋值text。虽然sizeToFit会最终改变lable的宽度和高度,但不会改变lable的居左和居上的大小,即frame里的X,Y的参数。而且lable的宽度改变的很小。比如你设的lable的宽度是300,sizeToFit以后宽度会变280(这个只是估算,具体以实际大小为准。)相当于高度的变化,宽度就变得小了。如果你不设置lable的宽度,sizeToFit后宽度就随机的,具体看下面的示例:
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 100, 50, 20)];
testLabel.text = @"weIU让我以任务女包女包\n二次不能不能传:\n1.的我我以为要问问嗯嗯非常丰富股份。\n2.问问无诶无诶无诶无诶weuwieuwieuwieuwieuwie任务和维护 问问偶尔";
testLabel.font = [UIFont systemFontOfSize:14];
// testLabel.textAlignment=NSTextAlignmentCenter;
testLabel.numberOfLines = 0;
[testLabel sizeToFit];
testLabel.textColor=[UIColor blackColor];
testLabel.backgroundColor=[UIColor yellowColor];
[self.view addSubview:testLabel];
sizeToFit是用范围很广,即使设置lable行距间距等等属性,也是可以正常展示的。
sizeThatFits和sizeToFit都可以实现文字自适应。区别在于sizeToFit会自动改变lable的大小,但sizeThatFits不会改变lable的size大小,这个只是计算出最优的 size 大小,如果想lable大小改变,需要重新赋值frame。
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 100, 300, 20)];
testLabel.text = @"weIU让我以任务女包女包\n二次不能不能传:\n1.的我我以为要问问嗯嗯非常丰富股份。\n2.问问无诶无诶无诶无诶weuwieuwieuwieuwieuwie任务和维护 问问偶尔";
testLabel.font = [UIFont systemFontOfSize:14];
// testLabel.textAlignment=NSTextAlignmentCenter;
testLabel.numberOfLines = 0;
//使用sizeThatFit计算lable大小
CGSize sizeThatFit = [testLabel sizeThatFits:CGSizeMake(200, 200)];
testLabel.frame = CGRectMake(testLabel.frame.origin.x, testLabel.frame.origin.y, sizeThatFit.width, sizeThatFit.height);
testLabel.textColor=[UIColor blackColor];
testLabel.backgroundColor=[UIColor yellowColor];
[self.view addSubview:testLabel];
注意:重新设置frame是最好以计算出来的size来赋值(这样的话,sizeThatFits后面的参数宽度和最终lable展示的宽度就相差不大的。但这个宽度不能超出屏幕外,否则超出屏幕外的文字会看不见的)。高度可以随便写,lable的高度最终是以文字的多少而定的。使用sizeThatFits方法时,在初始化lable的时候可以不用写frame的,可以在sizeThatFits方法后面重新赋值frame(我这里初始化的时候赋值了frame,所以重新赋值的时候,x,y的值我直接取了之前的testLabel.frame.origin.x和testLabel.frame.origin.y)。
boundingRectWithSize和sizeThatFits很类似,也是重新计算出size,不过比sizeThatFits多了几个参数。
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 100, 300, 20)];
testLabel.text = @"weIU让我以任务女包女包\n二次不能不能传:\n\r1.的我我以为要问问嗯嗯非常丰富股份。\n\r2.问问无诶无诶无诶无诶weuwieuwieuwieuwieuwie任务和维护 问问偶尔";
testLabel.font = [UIFont systemFontOfSize:14];
testLabel.numberOfLines = 0;
CGSize s = [testLabel.text boundingRectWithSize:CGSizeMake(320, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:testLabel.font} context:nil].size;//求文本的大小
// 并不是高度计算不对,我估计是计算出来的数据是 小数,在应用到布局的时候稍微差一点点就不能保证按照计算时那样排列,所以为了确保布局按照我们计算的数据来,就在原来计算的基础上 取ceil值,再加1;
CGFloat height = ceil(s.height) + 1;
testLabel.frame = CGRectMake(testLabel.frame.origin.x, testLabel.frame.origin.y, s.width, height);
testLabel.textColor=[UIColor blackColor];
testLabel.backgroundColor=[UIColor yellowColor];
[self.view addSubview:testLabel];
在使用boundingRectWithSize计算高度时,有时候不准确,需要注意一下几点
<1> 使用前2个方法来适配文字。
<2> 使用UITextView代替lable。使用方法如下:
UITextView *ysTextView = [[UITextView alloc] initWithFrame:CGRectMake(20, 100, 300, 10)];
ysTextView.text = @"我原以为的以为,那些苍老的画面\r\n都终将会老去,走吧\r\n走吧\r\n我的血和汗\r\n
\r\n某天,我听你说着\r\n看遍千山万水\r\n开心的如此忘杯";
// 可以将标签 ,进行转换
// NSString*ysStr =[ysTextView.text stringByReplacingOccurrencesOfString:@"
" withString:@"\r\n"];
ysTextView.font = [UIFont systemFontOfSize:14];
ysTextView.backgroundColor = [UIColor orangeColor];
ysTextView.textContainerInset = UIEdgeInsetsZero;
ysTextView.textContainer.lineFragmentPadding = 0;
ysTextView.scrollEnabled = NO;//当文字超过视图的边框时是否允许滑动,默认为"YES"
ysTextView.editable = NO;//是否允许编辑内容,默认为"YES"
[self.view addSubview:ysTextView];
CGFloat height=[(NSString *)ysTextView.text boundingRectWithSize:CGSizeMake(ysTextView.frame.size.width,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:ysTextView.font} context:nil].size.height;
CGRect textViewFrame = ysTextView.frame;
textViewFrame.size.height = height;
ysTextView.frame = textViewFrame;
上面UItextview方法是引用的别人的,详细的在这里 如何处理有换行的字符串,算高度.
首先使用Masonry是先添加lable到view上,然后在布局frame。由于sizeToFit需要先设置宽度(如果不设置宽度,默认是以整个屏幕的宽度来计算lable高度的)。所以使用Masonry布局时宽度就是固定了(如果你们的宽度不固定,就不要使用此方法)。
示例如下:先写死宽度,然后计算出高度,设置居左为0,居下-20,宽度和高度为lable的宽高
//定位城市
UILabel *cityLab = [[UILabel alloc]init];
cityLab.text = @"万余人业务员入围由入伍颜如玉我从不把VB如无意外有人问";
//设置宽度
cityLab.frame = CGRectMake(0, 0, 100, 0);
//换行
cityLab.numberOfLines = 0;
//文字自适应
[cityLab sizeToFit];
cityLab.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:cityLab];
[cityLab mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(0);
make.bottom.mas_equalTo(-20);
make.width.mas_equalTo(cityLab.frame.size.width);
make.height.mas_equalTo(cityLab.frame.size.height);
}];
如果有什么问题,欢迎下面评论指正。
参考链接:
如何处理有换行的字符串,算高度.
iOS 使用 boundingRectWithSize: 计算 UILabel 高度错误的解决方案
使用boundingRectWithSize计算内容高度的坑