不知不觉iOS系统已经更新到12了,技术的发展真是太快了,看来我也得与时俱进及时更新文章了(有些还是For iOS8的。。。)。这个系列主要是讲解iOS系统中的自动布局(Auto Layout),跟大家分享一下我自己关于界面自动布局的理解,如有错误请不吝指教。
一、视图定位的基本原理
视图(View)是一个用于显示内容的矩形区域,它是构成App界面的最基本单元。下图为计算器App的横屏界面,其中每一个计算器按键都是一个视图。
在平面直角坐标系中,要准确描述一个矩形需要确定以下四个布局属性(Layout Attribute),即水平位置x、垂直位置y、宽度w、高度h。只有上述4个布局属性都确定的情况下,该视图才能正确显示在界面中。
以上图为例,如果要将数字键5添加到界面中,则代码类似为:
UIView* number5View = [[UIView alloc] initWithFrame:CGRectMake(x, y, w, h)];
[parentView addSubview:number5View];
上述代码详细给出了该视图的4个布局属性的值(x、y、w、h),我们姑且称这种方式为“显式坐标定位方式”。
二、旧的界面布局方式及其缺点
请思考以下问题:
首先,当视图数量很多时,由于每个视图都需要精确给出4个布局属性的值,因此构建每一个视图非常繁琐而又容易出错。而且,当发生界面尺寸变化(例如横竖屏切换)时,你需要重新计算每个视图的新的布局属性值,工程量巨大。这显然不是一个令人满意的解决方法。
于是苹果给出了一个更好的解决方法,就是在创建视图的同时给出其相对于父视图的“对齐方式与缩放系数”,即autoresizingMask。当父视图发生变化时,通过每个子视图的autoresizingMask即可自动得出新的位置,而无需开发者提供。例如上图中的等号键,即可以指定其对齐方式为右对齐、下对齐,指定其缩放系数为固定宽度、固定高度。这样就保证了等号键总位于其父视图的右下角且宽高不变。
苹果解决问题的出发点是好的,通过给出界面变化的规则来自动计算出布局属性的值,从而省去开发者的工作。
然而autoresizingMask的问题在于:
因此在过去,很多时候开发者还不得不硬着头皮使用显式坐标定位方式来解决转屏(例如重写layoutSubviews方法),或者分别做横屏与竖屏两套界面。
这些开发者都能忍,然而噩梦才刚刚开始。。。
iPhone 4s及早期iPhone屏幕的尺寸是固定的(3.5寸屏:320*480),基本上在测试机上运行的效果就是用户运行的效果。但此后的新版iPhone为16:9的宽屏,分辨率也各不相同(4寸屏:320*568,4.7寸屏:375*667,5.5寸屏:414*736,5.8寸屏:375*812,6.1寸屏:414*896,6.5寸屏:375*896),另外有的app还需要同时支持iPad。难道所有这些设备都需要开发者去自己处理每个视图的精确位置,自己去处理转屏吗?
苹果当然也意识到了这些问题,因此在iOS 6发布时引入了自动布局(Auto Layout)与布局约束(Layout Constraint)的概念,意图从根本上解决问题,接下来我们就来说说自动布局的原理和使用方法。
三、自动布局的原理与使用方法
自动布局是对autoresizingMask的进一步改进,它允许开发者在界面上的任意两个视图之间建立精确的线性变化规则。所谓线性变化就是数学中的一次函数,即:
y = m*x + c
其中x和y是界面中任意两个视图的某个布局属性,m为比例系数,c为常量。例如,如果我们想描述数字键5紧贴在数字键8下方,我们可以建立如下规则:
每个线性变化规则称之为布局约束(Layout Constraint)。由于每个视图需要确定4个布局属性才能准确定位,因此一般来说都需要建立4个布局约束。
在下一篇文章中,我将详细介绍添加自动布局约束的方法,敬请关注。