实现一个在autolayout下有宽度约束后,自动确定高度的view
我曾经遇到过一个问题:需要实现一个自定义的label(类似于UILabel),同时需要兼顾UILabel的大小自适应的特性。这个label通常宽度是固定的,通过autolayout指定其宽度约束,但不指定高度,让其根据内容自适应。
我们知道UIView的方法intrinsicContentSize可以帮助我们确定视图在autolayout下的大小,从而避免我们去设置其宽高的约束。于是我采用了这样的解决方案:将label的宽度作为其属性,使用前我必须指定label的宽度,然后label本身通过其宽度属性确定高度。然而这个方法不太方便,因为宽度有时需要我们去计算,比如说它是屏幕宽度减去某个值。然而我是一个足够懒的程序员,不想每次去手动设置宽度。
后来思路终于有了,虽然不知道这是否是最佳方法,但至少解决了问题。在autolayout布局完成后,我们就可以知道视图的最终宽度了。这时我们可以通过
invalidateIntrinsicContentSize方法重新计算视图的大小。
代码如下:
@interface MyLabel : UIView @property (nonatomic, strong) UIFont *font;
@property (nonatomic, strong) NSString *text; @end
@interface MyLabel () @property (nonatomic, strong) UIFont *defaultFont; @end @implementation MyLabel - (instancetype)init
{
self = [super init];
if (self) {
self.defaultFont = [UIFont systemFontOfSize:];
}
return self;
} - (void)setText:(NSString *)text
{
_text = text;
[self setNeedsLayout];
[self setNeedsDisplay];
} - (void)layoutSubviews
{
[self invalidateIntrinsicContentSize]; // 在布局的时候强制重新计算大小
[super layoutSubviews];
} - (CGSize)sizeThatFits:(CGSize)size
{
UIFont *font = self.font ? self.font : self.defaultFont;
size.width = ceil(size.width); // 避免单行文本二次计算时被错误地计算为两行高度
if (size.width > ) {
return [self.text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil].size;
} else { // 此处是为了兼容不设宽度的情况(单行文本)
return [self.text sizeWithAttributes:@{NSFontAttributeName:font}];
}
} - (CGSize)intrinsicContentSize
{
return [self sizeThatFits:CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX)];
} - (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize
{
return [self sizeThatFits:targetSize];
} - (void)drawRect:(CGRect)rect
{
UIFont *font = self.font ? self.font : self.defaultFont;
[self.text drawInRect:rect withAttributes:@{NSFontAttributeName:font}];
} @end
让我们来测试一下:
MyLabel *label = [MyLabel new];
label.backgroundColor = [UIColor yellowColor];
[self.view addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) { // 这里并没设高度约束
make.left.mas_equalTo();
make.top.mas_equalTo();
make.width.mas_lessThanOrEqualTo();
}]; label.text = @"this is a long text. this is a long text.";

实现一个在autolayout下有宽度约束后,自动确定高度的view的更多相关文章
- 【纯css】左图右文列表,左图外框宽度占一定百分比的正方形,右上下固定,右中自动响应高度。支持不规则图片。
查看演示 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...
- Linux下svn提交文件后自动同步更新到网站目录
有时,对于多文件需要上传到服务器的时候将会很麻烦,但是如果使用svn的钩子脚本就容易实现本地提交svn后,自动同步代码文件到远程服务器的网站目录下,而不必手动上传了. 首先,在网站目录下checkou ...
- 怎样使用AutoLayOut为UIScrollView添加约束
1.在ViewController中拖入1个UIScrollView,并为其添加约束 约束为上下左右四边与superview对齐 2.在scrollview中,拖入1个UIView,为了便于区分将其设 ...
- js获取上一个月、下一个月格式为yyyy-mm-dd的日期
/** * 获取上一个月 * * @date 格式为yyyy-mm-dd的日期,如:2014-01-25 */ function getPreMonth(date) { var arr = date. ...
- 第三章 用SDK编译出第一个在Linux下的软件界面
第三章 用SDK编译出第一个在Linux下的软件界面 先创建一个工程目录“mkdir project1”,进入目录,创建main.cpp文件,编写代码如下: 代码内容暂时可以先不理解,先让程序跑起来再 ...
- tcl/tk实例详解——返回一个文件夹下所有文件的绝对路径
http://blog.csdn.net/dulixin/article/details/2133840 #所有代码如下,使用注释的方式讲解脚本#修改好文件夹和保存结果路径,可以把本文件直接拷贝进tc ...
- js input框输入1位数字后自动跳到下一个input框聚焦
// input框输入1位数字后自动跳到下一个input聚焦 function goNextInput(el){ var txts = document.querySelectorAll(el); f ...
- JavaScript一个页面中有多个audio标签,其中一个播放结束后自动播放下一个,audio连续播放
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python遍历一个文件夹下有几个Excel文件及每个Excel文件有几个Sheet
一. 解决问题: 工作中常会遇到合并Excel文件的需求,Excel文件数量不确定,里面的Sheet 数量是可变的,Sheet Name是可变的,所以,需要用到遍历一个文件夹下有几个Excel文件,判 ...
随机推荐
- J2SE知识点摘记(八)
1. 多线程指的是在单个进程中可以同时运行多个不同的线程,执行不用的任务.多线程意味着一个程序的多行语句可以看上去几乎同时进行. 同样作为基本的执行单元,线程是划分得比进程更小的执行单位 ...
- Delphi在StatusBar上绘制ProgressBar
首先,在TForm的私有域,也就是private下设置两个变量ProgressBar.ProgressBarRect,其中ProgressBar为 TProgressBar类型,ProgressBar ...
- vs错误【C1083 C1854 C4727】的若干解决办法(对预编译文件头的解释)
这几天写程序,无意间把编译中间文件给删了,然后就出现了C1083编译错误. xxx.cpp ..\commen\xxx.cpp(2) : fatal error C1083: 无法打开预编译头文件:“ ...
- IOSJSBRIGE商品内容模板
<p> 内容 </p> <script> window.onerror = function(err) { log('window.onerror: ' + err ...
- SDN 编程语言 p4(SDN programming language P4)
行业趋势,SND是未来. P4 是未来. SDN is inevitably, and P4 is inevitably. P4 = Programming Protocol-Independent ...
- &&与||的用法总结
a() && b() :如果执行a()后返回true,则执行b()并返回b的值:如果执行a()后返回false,则整个表达式返回a()的值,b()不执行: a() || b() :如果 ...
- 在cmd中输入ls命令出现“ls不是内部或外部命令解决
今天在学习sass查看目录遇到cmd输入ls提示不是内部命令 解决方法: 新建一个ls.bat文件 内容为: @echo off dir
- poj2186 Popular Cows --- 强连通
给一个有向图,问有多少结点是其它全部结点都能够到达的. 等价于,在一个有向无环图上,找出度为0 的结点.假设出度为0的结点仅仅有一个,那么这个就是答案.假设大于1个.则答案是0. 这题有环.所以先缩点 ...
- SQL语句一些特殊的用法
SQL语句一些特殊的用法 一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份s ...
- activity的打开关闭动画
Activity的打开关闭或者说相互跳转之间可以设置动画的.默认的打开关闭直接消失或出现,比较不优美,但是有的手机Rom对这个默认做了修改,比如红米HM1,默认的就是新页面自右向左滑动出现,自左向右滑 ...