IOS界面适配二: Auto Layout的使用(上)
上一篇讲了IOS中基础的距离单位,链接为 IOS界面适配一: Pt与Px的关系 ,使用距离单位可以定义我们程序中View的大小,但是,仅仅使用Pt定义大小是远远不够的。
比如,我们想让一个button距离手机左边界为20pt,右边界为20pt,距上为30pt,高度自身为20pt,如果在iphone5中(为320pt*568pt),我们要在代码中这么定义
以下代码写在ViewController中的viewDidLoad方法中:
UIButton * button = [[UIButton alloc]initWithFrame:CGRectMake(20, 30, 280, 20)];
[button setTitle:@"hello pt" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:button];
因为iphone5为320pt,所以这个button的宽度必须是280pt好了,看一下效果:
恩,看起来还符合要求,转一下试试呢:
等等,怎么跟设想的不一样呢?这是因为,我们在设置button的时候,就只考虑了Iphone5这个尺寸下的横屏,ios传统方法在判断view位置的时候,先看这个View在父View所载的位置,在看View本身的大小,所以,如果要是按我们刚开始的条件的话,button在父View的位置为(20,30) 大小为(280,20),但是当我们横屏的时候,父View变了,但button在父View的位置没变,大小也没变,才会出现这种情况
还有一种情况,我们换一个不同的分辨率的手机会怎么样:
可以看出,在Iphone6下就完全不对了,这是因为父View的大小变了,根据iphone5算出来的大小肯定会出错
上述说的是传统的限制View位置和大小的方法,需要注意的是:
当我们打开一个布局文件,并在里面拖动进控件的时候,或者在代码中使用initWithFrame方法的时候,都是使用的默认的传统限制方法,也就是上面的方法
虽然说这种方法简单,易懂,但是用起来局限性非常之大,几乎只能算是在iphone分辨率不变的时候用一下(那时候很多工程都不用布局文件,只用纯代码写),但在现在iphone分辨率多达4种,而且有的时候还要求支持横屏,使用上述方法可以说是寸步难行,下面我们使用Auto Layout解决上述问题
一.在布局文件中使用Auto Layout
先来看看apple官方对于Auto Layout的解释:
AutoLayout是一种基于约束的,描述性的布局系统。
关键词:
- 基于约束 - 和以往定义frame的位置和尺寸不同,AutoLayout的位置确定是以所谓相对位置的约束来定义的,比如x坐标为superView的中心,y坐标为屏幕底部上方10像素等
- 描述性 - 约束的定义和各个view的关系使用接近自然语言或者可视化语言的方法来进行描述
- 布局系统 - 即字面意思,用来负责界面的各个元素的位置。
总而言之,AutoLayout为开发者提供了一种不同于传统对于UI元素位置指定的布局方法。以前,不论是在IB里拖放,还是在代码中写,每个UIView都会有自己的frame属性,来定义其在当前视图中的位置和尺寸。使用AutoLayout的话,就变为了使用约束条件来定义view的位置和尺寸。这样的最大好处是一举解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义,原来在底部之上10像素居中的view,不论在旋转屏幕或是更换设备的时候,始终还在底部之上10像素居中的位置,不会发生变化。总之,使用约束条件来描述布局,view的frame会依据这些约束来进行计算.
以上部分内容摘自 : AutoLayout(自动布局)入门
下面说一下我个人对Auto Layout的见解:
1.当你对一个ViewA使用Auto Layout的时候,系统将会只使用Auto Layout中的条件来限制ViewA,而你原先对这个ViewA做的传统的设置frame或者大小都会立即无效
2.Auto Layout更接近于我们的自然语言,即它是一个更接近我们实际需求的工具
3.Auto Layout是基于约束的,一般来说,一个View至少需要4个约束才能确定其位置和大小
下面我们用Auto Layout解决上述问题:
约束使用方法;
1.拖进去一个button,在button上按住ctrl键+左键,拖动到主View上,如图
或者是在左边的Document Outline中
2.松手,会出现弹出框:
其中Leading Space to Container Margin为距离其左边界
Trailing Space to Container Margin为距离其右边界
Top Space to Top Layout Guide为距离其上边界
Buttom Space to Buttom Layout Guide为距离其下边界
设置其大小可以这样:
在其Width中填入约束宽度,在Height中填入约束高度
3.添加好约束后,改变其各个约束的值:
好了,我们设置此button的约束分别为距离屏幕左边界为20pt,右边界为20pt,距上为30pt,高度自身为20pt(从这里可以看出约束确实与实际问题非常相符),来看看效果:
iphone6横竖屏:
ipad air横竖屏:
非常好,跟预想一致,而且也非常的简单
那么,约束的原理是什么呢?
其实,约束差不多是下面一个公式组成的:
A = B * m + c
或者
viewA.attribute = viewB.attributs*multiplier + constant
我们看图中的距左的约束:
右边的四个框分别对应A = B * m + c运算式的 A , B , c , m
换算成语言即为,button的左边是屏幕左边界乘以一在加上20pt,跟我们的问题也是一样的
所以,加入我们想让button的顶部部是主View底部的四分之三的话,可以设置button的顶部与主View底部的约束中的的Multiplier为0.75,Constant为0
注意,这时候必须要先将button距离顶部的那个距离给删除掉,否则会出现约束过多导致混乱的情况
方法:
添加一个Buttom Space to Buttom Layout Guide的限制,将Multiplier为0.75,Constant为0,记得一定要将First Item 改为Button.Top,因为默认是Button.Bottom,如图所示:
运行即可查看效果,没有任何问题
通过布局文件使用Auto Layout就先说到这,其实这里面还有很多学问,以后有时间在写出来。
只使用布局文件来使用Auto Layout还是有一些不足,因为都是写死的,有的时候还是不能满足需求,我们还可以在代码中动态的改变布局文件中约束的Constant,或者动态的添加约束,这些将在下一篇中写出