我们知道,现在已经不像以前那样只有一个尺寸,现在最少的iPhone开发需要最少需要适配三个以上尺寸。因此以前我们可以使用硬坐标去设定各个控件的位置,但是现在的话已经不可以了,我们需要去做适配,也许你说可以使用两套UI或两套以上的UI,但那样不高效也不符合设计。iOS有两大自动布局利器:autoresizing和autolayout(autolayout是IOS6以后新增)。autoresizing是UIView的属性,一直存在,使用也比较简单,但是没有autolayout那样强大。如果你的界面比较简单,要求的细节没有那么高,那么你完全可以使用autoresizing去进行自动布局。也就意味着,现在,做IOS开发,屏幕适配是必须考虑的问题,而实现屏幕的适配的主要方式就是autolayout,而使用autolayout的关键步骤就是为控件添加相应的约束,
下面,我们就对约束的添加做一些说明。
一:通过系统提供的面板实现约束的添加
现在IOS6以上,系统会自动选择使用autolayout,在“show the file
inspector”面板中可以找到这个属性:
,如果选择了这个属性,那么在编辑区域的右下方就可以看到一些有关autolayout的选项了:
![](http://img.e-com-net.com/image/info10/f5be4a12b9b646b3b3faf35ab50fc99a.jpg)
首先,我们对对autolayout主要使用选项做一些说明,其实常用的主要是三个选项:
1.Align面板:
2.Pin面板:
细节说明:constraint to margin:选项的作用。这个属性是IOS8才添加的,它默认会在屏幕左右添加8个点的边距,也就意味着参考不是从屏幕边缘0的位置开始的,而是从8个点的位置开始的。一般来说,对于直接参考屏幕的控件,可以选择这个选项,如果是对于子控件,就没有必要选择了。
3.Resolve面板:
之后,我们介绍一下约束的添加方式。说白了,所谓的约束的本质就是为控件设置好frame属性值,只不过它添加了参照,而不像frame属性一样,只是针对控件本身。所谓参照就是它可以在其它控件或者父容器(如屏幕)有变化的时候,让自身的frame也产生合理的变化。下面以一个简单案例来说明一下约束的添加:
1.案例结果图:
2.添加相应的view控件,选择Pin面板,添加左和上的约束:
注意,不要选择更新约束,因为,如果约束不能正确的得到控件的frame属性,那么系统将很有可能不能正确的绘制出控件,只有当frame有四个属性(size(width.height),origin:(x,y))都能通过约束正确的计算出来才能更新约束。
3,设置宽高,我们需要view的宽度和高度都是屏幕的一半,但是,通过宽高属性却不能进行设置,否则就是固定宽高数值,以后不能进行屏幕的自动适配了。这个时候,面板就不够用,我们还需要使用到约束的修改属性面板,具体实现如下:
3.1先为view添加与屏幕右和下边距为0--view会填充整个屏幕
3.2找到约束,选择想修改的约束,我们想修改view与屏幕右和下的约束关系,那就一个一个选择这些约束进行修改,例如我们先选择右边距约束:
然后,查看约束的具体的属性:
那么一切都一目了然了。根据里面的序号读一遍就可以得到约束这个结果:红色view的最右边等于父容器的最右边数值乘以1加上0,很明显,就是红色view的最右边与父容器的最右边对齐,也就是等宽。所以根据示例结果,只需要将Multiplier修改为0.5,红色view的宽度就是父容器宽度的一半了,对于高度也是同样的处理方式。
说到这里,就不得不说一下在sb中还有一种方面的添加约束的方式:拖线。还是上面那个案例,刚才我们是通过添加四个方向的边距约束(特别是右,下)达到红色view的宽高和高度为父容器的一半,我们也可以通过直接设置红色view的宽高和父容器的宽高之间的关系来达到同样的效果。
1.拖线:
2.这里需要说明的是,拖线的方向决定了显示出的菜单项,如果往左下方向拖线,那么就可以看到添加当前控件与父容器左边距和底边距的选项。其它方向的拖线一样的道理。这里我们选择等宽等高(按住shift键可以同时添加多个约束):
添加后的约束列表:
3.修改添加了等宽等高约束:
读出来就是这样的:blueView的宽度等于父容器的宽度乘以0.5加上0,也就是宽度为父容器宽度一半。
其它几个view的制作方式基本一样啦。
二:通过代码实现约束的添加
代码添加约束其实就是将约束的属性面板所表达的含义使用代码进行描述,官方文档中,它的基本公式为:
意思是:第一个item的属性=(所参照的item的属性*倍数)+常量值。
1.添加约束的类: NSLayoutConstraint
2.添加约束的常用方法:
[NSLayoutConstraint
constraintWithItem:<#(第一个item)#> attribute:<#(某个属性)#> relatedBy:<#(属性与属性之间的关系)#> toItem:<#(参照的item)#> attribute:<#(被参照item的指定属性)#> multiplier:<#(倍数)#> constant:<#(增加的常量)#>];
3.参数的一些说明:
3.1.NSLayoutRelation:这是一个枚举,说明了属性之间的关系,需要注意的是,如果关系设置为等于,但是后期因为某些原因造成属性值不再是等于,则系统会给出相应的警告。
NSLayoutRelationLessThanOrEqual = -1,---小于等于
NSLayoutRelationEqual = 0,---等于
NSLayoutRelationGreaterThanOrEqual = 1, --大于等于
3.2. NSLayoutAttribute:item的属性:
NSLayoutAttributeLeft = 1,左
NSLayoutAttributeRight,右
NSLayoutAttributeTop,顶
NSLayoutAttributeBottom,底
NSLayoutAttributeLeading,左
NSLayoutAttributeTrailing,右
NSLayoutAttributeWidth,宽
NSLayoutAttributeHeight,高
NSLayoutAttributeCenterX,水平中心
NSLayoutAttributeCenterY,垂直中心
NSLayoutAttributeBaseline,基线
NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline,相当于,两者等价
------------下面是ios8之后的如果想添加默认边距的属性列表--------------
NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeTopMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeCenterXWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeNotAnAttribute = 0这不是一个属性,如果一个item的约束不需要参照其它的item,那么就使用这个。
说明:NSLayoutAttributeLeft| NSLayoutAttributeLeading,NSLayoutAttributeRight| NSLayoutAttributeTrailing的区别:
NSLayoutAttributeLeft和NSLayoutAttributeRight代表从左到右进行布局,NSLayoutAttributeLeading和NSLayoutAttributeTrailing代表从前到后进行布局,在我国NSLayoutAttributeLeft和NSLayoutAttributeLeading是一个效果的,布局习惯从左到右,但在有些国家地区(如中东地区等),布局习惯从右往左。那么NSLayoutAttributeRight反而和NSLayoutAttributeLeading是一个效果了,为了避免这些地区的问题,我们推荐使用:NSLayoutAttributeLeading和NSLayoutAttributeTrailing(比较安全和常用)
4.使用代码实现刚才的案例示例:
4.1一定要去除autoresizing属性
4.2创建约束
4.3根据约束添加规则添加约束到控件或者父容器
4.4代码:
-(void)viewDidLoad {
[superviewDidLoad];
//去除autoresizing属性
self.redView.translatesAutoresizingMaskIntoConstraints=NO;
self.view.translatesAutoresizingMaskIntoConstraints=NO;
//添加顶部约束
NSLayoutConstraint*constraintT=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeToprelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeTop multiplier:1constant:0];
//添加左边约束
NSLayoutConstraint*constraintL=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeLeft multiplier:1constant:0];
//添加宽度约束
NSLayoutConstraint*constraintW=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeWidthrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeWidth multiplier:0.5constant:0];
////添加高度约束
NSLayoutConstraint*constraintH=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeHeight multiplier:0.5constant:0];
//添加约束到控件--根据规则,添加到父容器
[self.redView.superview addConstraints:@[constraintT,constraintL,constraintW,constraintH]];
}
苹果还提供一种添加约束的VFL语言,有兴趣的也可以去看一下相关的文档说明。
当然,以后在进行开发过程中,效率至上,一般会使用第三个框架。如常用的框架有Masonry,一般第三方框架找到框架的帮助文档就能方便的学习和使用了。