实现一个在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文件,判 ...
随机推荐
- Hibernate get 和load的区别
1 load是要用的时候才从数据库去查询,get 是马上查询. 2 对于不存在的记录,get会报空指针异常,load会报 org.hibernate.ObjectNotFoundException: ...
- 如何让多个不同版本的jquery库共存
问题描述:公司的登录接口使用的是jquery1.4.2,因为我要使用一个jquery.pagination的分页控件(jquery1.7.2).如果我使用了1.7.2,登录接口会有问题. <sc ...
- DKNY_百度百科
DKNY_百度百科 DKNY
- 起启航-华夏互联与杰华网络合体结盟打造本土IT利舰
北京时间2013年9月9日消息: 领先的软件研发企业上海逐一软件科技有限公司与专业互联网推广运营机构南昌杰华网络开发有限公司达成协议,双方将建立紧密合作关系与集团运营体制,并在未来的10个月内进行相应 ...
- DBCP|C3P0参数详解
1.<!-- 数据源1 --> 2. <bean id="dataSource" 3. class="org.apache.commons.dbcp.B ...
- Trailing Zeroes (III)(lightoj 二分好题)
1138 - Trailing Zeroes (III) PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: ...
- MVVMLight Toolkit在Windows Phone中的使用扩展之一:在ViewModel中实现导航,并传递参数
MVVMLight是MVVM开发模式在Windows Phone平台下的一个开发框架,关于MVVMLight的基础使用,已经有人写的很好了,可以参照:MVVM.MVVMLight.MVVMLight ...
- python手记(36)
#!/usr/bin/env python #-*- coding: utf-8 -*- #code:myhaspl@qq.com import cv2 import numpy as np fn=& ...
- B树、B-树、B+树、B*树都是什么(转)
B树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于 ...
- iOS7 NavigationController 右滑手势问题
苹果一直都在人机交互中尽力做到极致,在iOS7中,新增加了一个小小的功能,也就是这个api:self.navigationController.interactivePopGestureRecogni ...