iOS 布局进阶:你真的会用 autolayout 么?

前言

iOS系统已经迎来了10.3.2版本,iOS软件开发发展至今已经相当成熟了。布局的方式从frame、size、center到如今强大的autolayout,将UI布局尽量的“自动化”和“智能化”,在很大程度上减少了程序员的工作量。

可能很多人体会过接手一个老项目通篇的frame是有多么的痛苦。在现如今的开发中,个人还是提倡使用自动布局(比如UITableview的高度自适应用法),以减少大量的UI计算,然而很多开发者可能写出的自动布局一点也不自动。

autolayout可以理解为:给界面设定规则,让界面随着数据的变化而做出符合规则的变化。

本篇文章重在解决自动布局中复杂的相互约束。

选择布局的工具

在“遥远的”过去,相信大家都用过(或者见别人用过)UIKit框架的下的NSLayoutConstraint,用原生的layout代码体量之大让人有些难以接受,好在大牛们写了一些轮子照福大家,比如业界最有名气的框架——Masonry。这里就不介绍Masonry的基础用法了,相关的文档已经满天飞了。

关于使用xib、storyboard还是纯代码布局,大家可以根据开发项目的进度要求和开发者人数来决定,反正他们布局的道理是一样的。

intrinsicContentSize

首先,我们得搞清楚intrinsicContentSize是什么。

一个View的约束确定需要两个东西,一个是位置,一个是大小。在日常开发中,我们发现给UILabel、UIImageView、UIButton实例写约束的时候,只需要给他们位置,而不需要给大小。这是因为它们指定了intrinsicContentSize(可以理解为内部通过内容计算出了一个合理的大小,我们可以不用指定它)。

<i>指定intrinsicContentSize 方法:重写UIView 中的 -(CGSize)intrinsicContentSize: 方法,在需要改变这个值时调用:invalidateIntrinsicContentSize 方法,告知系统值已改变(我们可以自定义指定intrinsicContentSize的类)</i>

所以,当我们不给这三种指定了intrinsicContentSize的控件的大小的时候,UI还是不会出错,而且可以通过intrinsicContentSize属性获取内部计算过后的大小。

模糊约束

模糊约束,就是Masonry中的 lessThanOrEqualTo、greaterThanOrEqualTo,也就是小于等于、大于等于。单独使用模糊约束很简单。

example:

需求:上图中label宽度和高度遵循intrinsicContentSize,但是长度不能超过父视图。 实现:Label距离左边10,纵向居中,距离右边小于等于10

优先级

优先级就是在两个约束冲突的时候,优先满足优先级高的约束。

example:

这个例子只是演示优先级,并无实际意义

其实通常情况下的优先级的使用很简单,这里我要讲的是视图的优先级,如下图

QQ20170603-095009@2x.png

这两个方法相信大家都不陌生(不管有没有用过),他们派上用场的条件是,该视图指定了intrinsicContentSize(固有大小),所以UILabel、UIImageView、UIButton都可以配置这几个方法。

当然,这是在nib文件里面进行可视化的配置,在代码里面是这样的(他们是UIView的方法):

- (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);

<ul> <li>contentHuggingPriority:拒绝变大优先级</li> <li>ContentCompressionResistancePriority:拒绝缩小优先级</li> </ul> 换言之,拒绝变大优先级越高,它就不会变大,拒绝缩小优先级越高,它就不会缩小(额,有点废话的感觉)。举个例子见道理:

example:

需求:A和B相距10pt,A的宽度只能和文本一致(A尽量遵守指定的intrinsicContentSize)

实现:

step 1:先固定A和B的位置,然后他们相距10,把约束加上过后会报警告

step 2:我们做以下操作就能解决

拒绝变大优先级的使用

当然,这只是一个默认情况(提醒各位,不光是写业务逻辑,写布局也需要考虑极限情况,这样才能写出完美的布局),当A的文本变化的时候会这样:

极限情况

step3:以下的处理就顺理成章了

拒绝变小优先级的使用

当然,到目前为止算了完成了需求,但是在实际开发中还有一个问题需要考虑,就是A的内容过长,将B挤压为0了(_)

B的宽度被挤压为0了

step4:这时候,我们需要给B一个最小的宽度,避免“人间蒸发”,实现这个并没有想象中的那么简单,方法也很多,下面只讲解一种:

给B一个宽度,优先级为默认的1000

设置B宽度优先级为250 ![B的宽度再一次压缩为0](http://upload-images.jianshu.io/upload_images/2909132-aa15868f6f9f62d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

最终解决

结语

布局的重点内容无非就以上讲解的东西,它们单独拎出来时,大家都觉得非常的简单。是否能写出一个完美无bug的布局,往往需要结合它们使用(固定约束、模糊约束、优先级),当布局元素很多且极其灵活的时候,才是考研iOS工程师布局UI能力的时候。

大家觉得读完本篇文章有些许收货,可以点赞或留言,觉得写得太low也可以点赞留言

由于篇幅原因,没有列举实际业务需要的例子,之后有空会写一写 。 _

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏君赏技术博客

百思不得姐数据挖掘第二篇

首先进入的是启动的界面,我们已经在上一篇做好了。第一次启动之后会出现一个宣传的视频,是下面的界面。

16310
来自专栏星流全栈

React v15.0 正式发布!

13830
来自专栏Material Design组件

Human Interface Guidelines —— Labels

15660
来自专栏前端架构

web app响应式字体设置!rem之我见

之前做沙漠教育的时候,直接以设计图为准,然后强暴式,缩放处理。简单。直接,粗暴!但是,开发快。……一劳永逸!

482110
来自专栏Coco的专栏

BAT及各大互联网公司2014前端笔试面试题--Html,Css篇

31050
来自专栏小狼的世界

使用OmniGraffle制作原型图

原型图设计是一个艺术创作的过程,所以我们应当使用能够提高工作效率、激发创作灵感的工具,让工具为创作服务,而不是为创作去学习如何使用工具。从这一点上说,我觉得Ma...

42630
来自专栏极客慕白的成长之路

React . js 是怎样炼成的?

内容整理自 2014 年的 OSCON - React Architecture by vjeux(https://speakerdeck.com/vjeux/...

17340
来自专栏极客编程

最全的资源教程 转

88920
来自专栏进击的君君的前端之路

HTML5

75950
来自专栏Web行业观察

移动前端兼容操作总结

手机设备屏幕尺寸不一,做移动端的Web页面,需要考虑在安卓/IOS的各种尺寸设备上的兼容,这里总结的是针对移动端设备的页面,设计与前端实现怎样做能更好地适配不同...

27830

扫码关注云+社区

领取腾讯云代金券