iOS之Autolayout
做过Android应该都知道相对布局这个概念,一个控件以另一个控件为参照进行布局,那么即使屏幕变化,布局也会随着进行微调,以达到良好的视觉效果并且保持了代码的可拓展性。
随着iPhone5 的面世,iPhone的屏幕比例也失调了。今年的WWDC就有了iOS的新特性auto layout,当然这个自己也还在学习当中。这里就把自己这几天的收获记录下…..
首先讲讲auto Layout在xib中的应用,这里有两篇raywenderlich网站的帖子讲的非常好,讲得很透彻,本人跟着步骤一步一步做下来已经大概明白auto layout 的一个思路了,很有启发性,建议大家先看,如果有xcode 4.5的话,最好跟着练一下。
再者,本人的习惯,UI基本都是用代码敲出来的。然而,自动布局用到纯代码上,就没有原来那么方便,但是逻辑上还是很好理解的。苹果的文档是一定要看的。其实自动布局,在Mac上去年就已经开始用了,官方有3个Demo,虽然是os x的代码,但是原理是一样的,可以好好研究。
个人觉得,之前界面思路是固定的,因为屏幕的比例是固定的,每个UI都可以有自己确定的坐标和大小,虽然之前的也有autoresizing但是还是有局限性的,然后对于横竖的UI布局,要么另匹配代码,要么就是另用一个xib,毕竟也不是很方便。
自动布局就很好的解决了上述问题。
好了下面我们来看下自动布局,
如图,我们之前布局一个button的话,肯定先指定的它的frame。有经验的程序员,会尽量不把代码写死,可能会参照屏幕的frame或是当前界面的frame,按照一定比例取frame值。所以一个button,在坐标系中,坐标确定了,位置也就确定。因为前5代iPhone屏幕比例是一样的,所以这也不会带来问题。但是iPhone5出来了,需要做些调整了。auto layout去布局的时候,首先我们要选择一个参照对象,根据参照对象设置参照值,根据参照对象和参照值就可以知道自己的位置了。就如上图的button,我们知道,button距离屏幕的左边缘的间距和上边缘的间距就可以的确定button的位置了,autolayout还有一个独特的地方,就是UI可以根据字体大小和字数自动计算大小,当然你也可以自己指定大小。这样button在屏幕的相对位置就不变了,不管是横屏还是竖屏。
当然这里优势还并不明显,那么当有两个button时呢?我们在看下下图。这里第二button以第一button为参照,进行布局。以此类推。
但是我为什么要用自动布局呢?看下下面这个图。
以你的经验,代码量会是多少?或是是不是要再加一个xib?
我们知道,如果界面整体的布局是确定的,就如图所示,那么很适合进行自动布局,因为相对位置确定了,相对关系确定了,尺寸和位置系统会自动给我们计算出来,所以这里只要一套代码或是一个xib就可以很好的适用任何一个屏幕(可能有点绝对)。
其实,auto layout 的关键就是关系的确定,要十分确定,如果是个模棱两可的关系,很多时候系统是会迷糊会报错,即使有时候绘制出来了,也会丢给你一大堆它不确定的警告。所以构建的时候要想好布局,选好合适的参照对象,最后保证语法没有错误,那么一个效果良好的布局会就实现了。
这里再给大家介绍下语法,这个呢apple文档里有,我这里算是摘抄下
1:理解概念
Auto Layout中文翻译过来意思是自动布局,通过内定的Constraint(约束)和各项条件来计算出合理的布局.而这个合理的布局,符合我们的的预期和意图.
将我们想象中的结果展现出来.Constraint的设定非常灵活,实现一种布局的方法可以通过多Constraint套来完成.
以下几点是我们在开始使用之前必须弄清楚的事情:
1:我们要抛弃以往旧的布局方式不再去关注View的Frame,Center,和autoresizing. 因为这些坐标和大小的定位都可以通过来Auto Layout完成.
2:理解每一种Constraint的含义,否则,当你去看别人的实现的Constraint时,就会有种看天书的感觉.
3:按意图设计,一切按我们理想中的效果去布局,只要约束设定的合理,就一定能够完成目标布局.
2:开始使用
先从Interface Builder开始吧. 打开某个Xib或者StoryBoard,
在右侧Show in file inspector里面找到Ues Autolayout,将其勾选.如下图:
自此,Autolayout便启用成功,autoresizingMask被废弃.其所有以往的功能和特性都被Autolayout取代.
现在我们定位控件位置的方式,不再像以前一样,计算好每一个控件具体的位置,x是多少,y是多少.
而是思考,这个控件离左边是相隔多少距离,或者离顶部或底部相隔多少距离.
而有些规则性的事情还是类似的,比如我们定位一个控制的位置,一定要有x,y两个坐标点同时有值,少一个都不能正常显示.
同样Autolayout在创建约束时也一样,在思考完离顶部距离以后,还需要思考离顶部距离,否则控件的显示位置一样无法正常显示.
换言之,要让Autolayout计算出合理的位置,需要保证水平距离和垂直距离同时存在. 否则IDE,都会给出警告,提示这样的布局Ambiguous Layout(模凌两可)
接下来,让我们来熟悉一下Interface Builder提供哪些实现Autolayout的功能:
观察一下界面预览右下角,有一排如下图这样的按钮:
这些是Interface Builder用来创建Constraint的主要方式,同时,我们也可以在Xcode的菜单栏中找到这些功能,如下图:
这些功能分别如下图中描述的那样:
如果是从代码层面开始使用Autolayout,需要对使用的View的translatesAutoresizingMaskIntoConstraints的属性设置为NO.
即可开始通过代码添加Constraint,否则View还是会按照以往的autoresizingMask进行计算.
而在Interface Builder中勾选了Ues Autolayout,IB生成的控件的translatesAutoresizingMaskIntoConstraints属性都会被默认设置NO.
3:从旧的IB布局中转换成Auto layout
4:熟练使用Interface Builder
5:通过代码来构建自动布局
代码创建的约束有两种方式:
1:常规约束,写法非常冗长,但能实现所有的约束方式以及非常特殊的约束方式,代码如下:
- //实例化Button
- button1 = [[UIButton alloc] initWithFrame:(CGRectZero)];//这里不再需要去刻意指定x.y等坐标.
- [button1 setTitle:@"yushuyi" forState:UIControlStateNormal];
- [button1 setBackgroundColor:[UIColor redColor]];
- [button1 sizeToFit];
- [button1 setTranslatesAutoresizingMaskIntoConstraints:NO];//将使用AutoLayout的方式来布局
- [self.view addSubview:button1];
- //创建了一个水平居中父视图的约束
- NSLayoutConstraint *constraint = [
- NSLayoutConstraint
- constraintWithItem:button1
- attribute:NSLayoutAttributeCenterX
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeCenterX
- multiplier:1.0f
- constant:00.0f
- ];
- [self.view addConstraint:constraint];//将约束添加到对应的父视图中
- //继续创建了一个位于父视图底部相隔20距离的约束
- constraint = [
- NSLayoutConstraint
- constraintWithItem:button1
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeBottom
- multiplier:1.0f
- constant:-20.0f
- ];
- [self.view addConstraint:constraint];
值得注意的是,添加约束之前一定要将子视图优先addSubview到父视图中,否则在添加约束时会产生编译器警告.
而我们在理解的时候,可以通过这种方式来理解.
item1.attribute = multiplier ⨉ item2.attribute + constant
2:可视化格式语言约束
所谓可视化格式语言约束,是一种很直观的理解方式,当然,前提是你已经熟练理解这套语言的规则.
通过可视化语言可以一次性创建多个约束. 这对于第一次方式来说,是相当方面和容易理解的.但可视化语言不是所有约束都能满足.
我们可以用正则表达式的学习方式来学习这项可视化格式语言.举例代码如下:
- //创建需要参与约束规则的对象字典 <span style="font-family:Arial,Helvetica,sans-serif">表示这三个Button将参与Autolayout的约束处理</span>
- NSDictionary *viewsDic = NSDictionaryOfVariableBindings(deleteButton,cancelButton,nextButton);
- NSArray *constraints = nil;
- constraints = [NSLayoutConstraint constraintsWithVisualFormat:
- @"H:|-25-[deleteButton(==cancelButton@700)]-(>=8)-[cancelButton(140)]-[nextButton(nextButtonWidth)]-rectY-|"//水平 可视化格式语言
- options:NSLayoutFormatAlignAllTop //对齐功能
- metrics:@{@"rectY":@5,@"nextButtonWidth":@30}//指标参数
- views:viewsDic];//参与约束的对象字典
- [self.view addConstraints:constraints];
- constraints = [NSLayoutConstraint constraintsWithVisualFormat:
- @"V:[nextButton]-|" //垂直 可视化格式语言
- options:0 //无条件
- metrics:nil//不带指标参数
- views:viewsDic];//参与约束的对象字典
- [self.view addConstraints:constraints];
- // [deleteButton setContentHuggingPriority:249 forAxis:UILayoutConstraintAxisHorizontal];
这简单的十行代码,如果你没有学习过Autolayout也会看出一些猫腻,似乎看懂了.但又似懂非懂.接下来就详细解释一下
在解释之前,先看看上面这些代码执行后的效果,竖屏如下图:
横屏:
三个按钮位于视图的底部,有大有小,中间有间隔.
3:通过第三方Auto Layout的增强类别包,来实现约束的创建
https://github.com/smileyborg/UIView-AutoLayout
UIView-AutoLayout的出现如作者所说,其实现思路来源于Interface Builder. 所以在其API命名方面可以找到很多Interface Builder的影子,
博主极力推荐这个类库,通过它来创建约束是一件非常愉快的事情,思路清晰,当有个前提是,你已经理解了Auto Layout各项规则.
constraintsAffectingLayoutForAxis //约束检查 为什么这个View 这样显示
systemLayoutSizeFittingSize
所以这些语法,一但熟悉了逻辑还是比较清晰的。
浙公网安备 33010602011771号