使用Auto Layout实现和适配不等高复合型cell

前言

春节快到了,挺久没回家的,在帝都离回家的日子也越来越近,反而觉得有些恐慌,年前最后一篇了,写点关于cell屏幕适配的技巧吧,希望能给大家带来点帮助,这篇大都是操作性的,我尽可能截一些图理解,大家观看的时候耐心加载图片,OK,废话不多少说,下面开始。

正文

现在实践中慢慢尽可能少的代码去实现UI部分,大都使用IB去操作,之前实现一些高度不统一cell,而且可能某些控件隐藏或者显示,都是拿到数据源通过代码去计算每行cell的高度,也比较耗费时间,接下来就聊聊我是怎么用Auto Layout去实现的。


cell.png

上面举个简单例子,cell内部只有两个控件,一个ImageView和Label,说下需求:

  • 假设UI给的效果图是6p的,图片在6p上是100*100的,在别的屏幕按比例缩放。
  • label的字数不固定。
  • label可能显示或隐藏,cell需要根据label的显示和隐藏去适应高度。

先来一步步来实现上面三个需求....

一、子控件根据父控件比例缩放

1、先在xib中拖出上面两个控件,选中图片,设置距离cell上面和左边的边距都为10,图片的x和y已经确定了,这里就不上图了,大家应该知道。
2、为了图片不变形,先设置图片相对自身的宽高比,选中图片,往自身拖出约束,选择Aspect Ratio


Snip20160131_16.png

Snip20160131_14.png

再选中刚刚添加的约束,在右边栏按图编辑好对应宽高比,这里设置宽高1:1。


Snip20160131_7.png

3、接下来是按屏幕宽度缩放,选中图片拖向它所在的父控件,这里的父控件就是contentView,同样选择Aspect Ratio。

选中约束还是在右边栏去编辑好,如下图,这里是相对6p的效果图,所以设置100:414,需求的第一步已经完成了。
Snip20160131_17.png
二、Label内容自适应

1、还是先设置Label上部距离图片底部边距以及距离父控件左、右侧边距,这三个约束已经给定label内容显示的最大宽度。
2、很重要的一步,选中label在上面栏点击Editor,选中Size to Fit Content,或者使用快捷键com = ,意味着label的尺寸根据它的内容去适应,根据你上一步给定的那个宽度去折行,同时记得label的行数设置为0。


Snip20160131_18.png

3、很显然现在运行cell的高度是不会根据内容适应高度的,再label添加一个下面距离父控件的约束,这里也是设为10的边距,现在
cell的高度 = 图片的上边距 + 图片高度 + 文字和图片边距 + 文字高度 + 文字下面距离父控件边距,是不是有些像我们平时使用Auto Layout设置scrollView的约束,你可以这么理解,父控件的内容根据子控件去撑满。


Snip20160131_19.png

最后还需要一行代码,也是最关键的一步,设置tableView的estimatedRowHeight,顾名思义就是预设的行高,你可以随意设置一个值,当cell滑动时会去计算出真实的行高,这样前两个需求就做完了,Auto Layout已经帮我们计算好了行高,是不是很方便才写了一行代码,比较遗憾的事这个方法适用比较简单的cell,复杂的用此方法可能会有卡顿问题,所以根据复杂程度使用。
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.example1TableView.estimatedRowHeight = 100;
}

三、设置约束优先级

先简单介绍一下约束优先级,具有优先级1000(UILayoutPriorityRequired)的约束为强制约束(Required Constraint),也就是必须要满足的约束;优先级小于1000的约束为可选约束(Optional Constraint)。默认创建的是强制约束。它分为
高优先级:UILayoutPriorityDefaultHigh,
低优先级:UILayoutPriorityDefaultLow,
内置的最低优先级:UILayoutPriorityFittingSizeLevel

typedef float UILayoutPriority;
static const UILayoutPriority UILayoutPriorityRequired NS_AVAILABLE_IOS(6_0) = 1000; // A required constraint.  Do not exceed this.
static const UILayoutPriority UILayoutPriorityDefaultHigh NS_AVAILABLE_IOS(6_0) = 750; // This is the priority level with which a button resists compressing its content.
static const UILayoutPriority UILayoutPriorityDefaultLow NS_AVAILABLE_IOS(6_0) = 250; // This is the priority level at which a button hugs its contents horizontally.
static const UILayoutPriority UILayoutPriorityFittingSizeLevel NS_AVAILABLE_IOS(6_0) = 50; // When you send -[UIView systemLayoutSizeFittingSize:], the size fitting most closely to the target size (the argument) is computed.  UILayoutPriorityFittingSizeLevel is the priority level with which the view wants to conform to the target size in that computation.  It's quite low.  It is generally not appropriate to make a constraint at exactly this priority.  You want to be higher or lower.

现在我们想当label隐藏时图片距离cell的底部也为10,现在就需要再添加一条图片距离cell底部为10的下边距,这时候我们发现会有冲突,选中这条约束把优先级设置得低一些,会发现冲突消失了,约束变成了虚线,把之前图片相对label的边距的约束拖到.h中作为cell的属性。


Snip20160131_20.png

在tableview代理方法里面判断label显示或隐藏来修改优先级

cell.imageBotton.priority = cell.label.hidden ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;

当label隐藏时把优先级设置为UILayoutPriorityDefaultLow,显示时设置UILayoutPriorityDefaultHigh,只要是比图片底部相对父控件边距那条约束低就行了。
这里有一个注意点:

  • 不允许将优先级由小于1000的值改为1000,例如,如果将优先级由250修改为1000,则会抛出异常,控制台会打印以下:
    Snip20160131_1.png

    所有操作都做完了,现在运行效果如下:
    result.gif

    最后是这次的代码:
    https://github.com/ShelinShelin/AutoLayoutDemo
    之前的一些例子请点击:
    https://github.com/ShelinShelin 欢迎右上角⭐️Star,谢谢!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容