实现一个在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文件,判 ...
随机推荐
- Oracle EBS-SQL (BOM-1):检查供应类型错误.sql
--检查供应类型错误 SELECT MSI.SEGMENT1 物料编码, MSI.DESCRIPTION 物料描述, DECODE(MSI.WIP ...
- 如何在IE8下调试OCX控件
第一种方式 多进程模式下, 在IE8打开web页面, 然后在调试菜单选择附加到进程, 这时看到2个IE进程, 选择没有带标题的, 也就是主进程, 就可以正常调试了. 此方式比较麻烦, 不能F5直接启动 ...
- c++ 关于类构造函数的初始化列表
除了性能问题之外,有些时场合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表 常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面 引用类型,引用必须在定义的时候初始化,并且不能重 ...
- #include <thread>
1 detach 脱离当前主线程,自由执行,乱序; 2 join() 等待模式,执行完再执行下一个 3 std::this_thread::get_id() 获取当前线程编号 4 std::threa ...
- iPhone 禁止 Safari 页面上下拖动反弹
解决方法: <body ontouchmove="event.preventDefault()" > 手机端设置: <meta content=&q ...
- Asp.net的对Excel文档的导入导出操作
刚刚初入职场,在休闲的时间写下了项目中用到的对Excel文档操作的方法以及总结,多的不说,直接上代码 public static void CreateExcel(DataSet ds, string ...
- .aspx.cs传值与取值
1:.aspx中post传值 $.post("ABP_ExchangeRatelz.aspx", { option: "isdelete", Ori_Curre ...
- [Java]HashMap的两种排序方式
先将 Map 中的 key 和 value 全部取出来封装成 JavaBea 数组,再将这个数组排序,排序完成后,重新写回 Map 中,写回时采用 LinkedHashMap 可以保证迭代的顺序. 下 ...
- Cookie已经过时,细看Facebook, Google, Apple如何追踪用户
http://www.infoq.com/cn/news/2014/10/cookie-facebook-google-apple 链接地址 Cookie,有时也用其复数形式Cookies,指某些网站 ...
- 虚拟机NAT模式主机ping不通虚拟机解决方案
本篇没有抓包,只是简单一个实施.需要的童鞋可以拿走这个方法. 虚拟机与真机通信三种模式, 桥接模式,NAT 模式 ,HOST 模式. 桥接就是在真机的网络上模拟一个网卡,给虚拟机申请一个和真机在同一个 ...