我曾经遇到过一个问题:需要实现一个自定义的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的更多相关文章

  1. 【纯css】左图右文列表,左图外框宽度占一定百分比的正方形,右上下固定,右中自动响应高度。支持不规则图片。

    查看演示 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...

  2. Linux下svn提交文件后自动同步更新到网站目录

    有时,对于多文件需要上传到服务器的时候将会很麻烦,但是如果使用svn的钩子脚本就容易实现本地提交svn后,自动同步代码文件到远程服务器的网站目录下,而不必手动上传了. 首先,在网站目录下checkou ...

  3. 怎样使用AutoLayOut为UIScrollView添加约束

    1.在ViewController中拖入1个UIScrollView,并为其添加约束 约束为上下左右四边与superview对齐 2.在scrollview中,拖入1个UIView,为了便于区分将其设 ...

  4. js获取上一个月、下一个月格式为yyyy-mm-dd的日期

    /** * 获取上一个月 * * @date 格式为yyyy-mm-dd的日期,如:2014-01-25 */ function getPreMonth(date) { var arr = date. ...

  5. 第三章 用SDK编译出第一个在Linux下的软件界面

    第三章 用SDK编译出第一个在Linux下的软件界面 先创建一个工程目录“mkdir project1”,进入目录,创建main.cpp文件,编写代码如下: 代码内容暂时可以先不理解,先让程序跑起来再 ...

  6. tcl/tk实例详解——返回一个文件夹下所有文件的绝对路径

    http://blog.csdn.net/dulixin/article/details/2133840 #所有代码如下,使用注释的方式讲解脚本#修改好文件夹和保存结果路径,可以把本文件直接拷贝进tc ...

  7. js input框输入1位数字后自动跳到下一个input框聚焦

    // input框输入1位数字后自动跳到下一个input聚焦 function goNextInput(el){ var txts = document.querySelectorAll(el); f ...

  8. JavaScript一个页面中有多个audio标签,其中一个播放结束后自动播放下一个,audio连续播放

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Python遍历一个文件夹下有几个Excel文件及每个Excel文件有几个Sheet

    一. 解决问题: 工作中常会遇到合并Excel文件的需求,Excel文件数量不确定,里面的Sheet 数量是可变的,Sheet Name是可变的,所以,需要用到遍历一个文件夹下有几个Excel文件,判 ...

随机推荐

  1. eclipse 打开文件目录

    用简单的配置方式 eclipse打开当前文件所在文件夹的插件 Run-->External Tools-->External Tools Configurations... new 一个 ...

  2. 供应类型与计划分类一致性检查(INV)

    应用 Oracle Inventory 层 Level Function 函数名 Funcgtion Name CUXINVIMM 表单名 Form Name CUXINVIMM 说明 Descrip ...

  3. 关于Apple Pay,一篇让你不看就会后悔的文章

    编者按:本文作者康上明学为“小米生活”产品经理,在苹果Apple Pay发布后,他对该产品做了深入研究,带来这篇文章. 对于 Apple Pay ,我有几个疑问: 线下支付是一个庞大复杂的流程,当中涉 ...

  4. Adobe Acrobat 9 Pro Extended 9.4简体中文完整免激活注册版

    Acrobat9 Pro最近升级比较频繁,如今已经升级到了Acrobat 9 Pro Extended 9.4版.亿品元素上曾经分享过Acrobat Pro Extended简体中文版 9.3.3 优 ...

  5. ViewPager + HorizontalScrollView 实现可滚动的标签栏

    这是一个可滑动的标签栏的自定义控件,参考此文章http://blog.csdn.net/fx_sky/article/details/8990573,我将主要的功能整合成一个类,配上2个特定的布局即可 ...

  6. JavaEE Tutorials (16) - Java消息服务概念

    16.1JMS API概述198 16.1.1什么是消息传送198 16.1.2什么是JMS API199 16.1.3何时使用JMS API199 16.1.4Java EE平台如何使用JMS AP ...

  7. csu 1563 Lexicography

    题意:给出一堆字母 问这些字母组成的字符串中第k大的 排列组合,具体看代码 //寒假集训被何柱大大踩好惨(>_<) #include<cstdio> #include<i ...

  8. [LeetCode][Python]Tow Sum

    # -*- coding: utf8 -*-'''https://oj.leetcode.com/problems/two-sum/ Given an array of integers, find ...

  9. _extend用法总结

    针对对象数组: 后面的属性会覆盖更新前面的属性 看代码: <!DOCTYPE html> <html> <head> <meta charset=" ...

  10. cf-A. Wet Shark and Odd and Even(水)

    A. Wet Shark and Odd and Even time limit per test 2 seconds memory limit per test 256 megabytes inpu ...