AutoLayout之纯代码布局
2014-12-13 10:04
127 查看
AutoLayout之纯代码布局
基础篇
VFL (Visual format language) 格式字符介绍
注:不明白的没关系,后面用到时候会介绍。
主要API
1 2 3 4 | + (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views; |
API参数介绍:
format: 这个参数就是 VFL 语句,如:V:|-20-[label];
opts: 枚举参数,默认为0,具体跟据你所实现的需求去选择你想要的枚举;
metrics: 一个字典,里面的key对应的是你在
format中设置的。比如这句:
V:|-20-[label(==heigth)],表示
label的高度为
heigth,那么这个参数去哪里找呢?就是这个字典里面相应的key对应的值。
views: 这是传所有你在 VFL 语句中使用到的
View。
API使用示例:
1 2 3 45 | UILabel *label = [[UILabel alloc] init]; label.backgroundColor = [UIColor lightGrayColor]; label.textColor = [UIColor whiteColor]; label.text = @"纯代码自动布局"; /* 要实现自动布局,必须把该属性设置为NO */ label.translatesAutoresizingMaskIntoConstraints = NO; /* 添加约束条件前一定要先将控件添加到superView上 */ [self.view addSubview:label]; /* 水平方向约束条件 */ NSArray *constraints1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[label(==200)]" options:0 metrics:@{@"margin":@60} views:NSDictionaryOfVariableBindings(label)]; /* 垂直方向约束条件 */ NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[label(==heigth)]" options:0 metrics:@{@"heigth":@40} views:NSDictionaryOfVariableBindings(label)]; [self.view addConstraints:constraints1]; [self.view addConstraints:constraints2]; |
说明:
解释一下上面使用的 VFL 语句:第一句
H:|-margin-[label(==200)]
H:代表水平方向
|代表父视图(superview)
-表示间隔(后面会详细讲解)
margin是
label与父视图左边的间距,也就是
@{@"margin":@60}这个字典中
margin对应的值60
[label]表示此约束是针对
label的
(==200)表示
label的宽度为200
pts
整句话的意思就是给
label添加
x坐标为60,宽度为200
pts 的约束条件;
第二句
V:|-50-[label(==heigth)]
V:表示垂直方向
|代表父视图(superview)
-表示间隔
50代表
label与父视图的顶部的间隔为50
(==heigth)表示
label的高度为
height(@{@”heigth”:@40}字典中对应的40
pts)
完整的描述为,给
label添加
y坐标为50,高度为40的约束条件。
还需要说明的一点是 API 中的 views 是一个字典,这个字典中传入的是你在这个约束条件中用到的所有的 view。如上列中对 label 进行布局,所以这个 views 就是 label。
运行结果如下所示:
通过上面这个例子你应该掌握至少以下几点:
使用
H:和
V:的区别和作用
如何设置宽度和高度
metrics字典的使用
卖个关子:将上面的
H:|-margin-[label(==200)]改为
H:|-[label(==200)],
V:|-50-[label(==heigth)]改为
V:|-[label(==heigth)]再在
iOS 7 和 iOS 8 模拟器上面运行项目看看结果。然后,再去掉第一句的
H:看看,你肯定会有所发现。继续阅读本文,你都会找到所有的答案。
进阶篇
上面只是简单的介绍了下主要API的基本使用,对于初学者来说,难点应该在于如何书写 VFL 语句。但是,还有一点是更重要的,这一点就是你要能够领悟到,怎样添加约束条件才能将一个 UI 控件布局到你想要的位置。对于这一点,多练习,就会很快掌握的。下面,我将利用图(一图胜前言啊)文的形式来为你剖析 AutoLayout 的 VFL 语句的含义,进一步让你熟知这种语法。
第一句:
H:|-[view]-|
理想中的效果应该是这样的,如下图:
我先解释下这句 VFL 语句的含义,给
view添加离父视图左右边缘各
20 pts的距离。此时,可能有读者会问了,哪里来的
20 pts?在此说明一下,在使用
H:水平方向时,子视图相对于父视图的间距如果不明确给出的话(明确给出是这样的,比如
H:|-30-[view]-|,这个
30 pts就是左边距),
-代表的就是
20 pts。请注意,我说的是水平方向相对于父视图。
你是否还记得我前面卖的那个关子呢?现在你应该明白了,相对于父视图时,使用
V:和
H:时,
-所代表的值各为多少了,并且你应该注意到在
iOS 7 跟 iOS 8 之间的区别了。
再解释下上面为什么说是理想中,如果你编写了代码,并实际运行了项目,不用我说你也会发现问题的所在。问题在于,这个约束加上后,你根本就看不到
view在哪。那么,你再把这个
view换成
UILabel或者
UIButton并且给他们的
title属性赋值再看看效果。
你又发现了“新大陆”,这里需要提一个新的东西
intrinsicContentSize,也就是控件的内容尺寸。控件的内容尺寸是根据内容所定的,再看看你写的
label和
button他们的高度是不是就是标题文字的高度呢?如果你把上面的
H:|-[view]-|改为
H:|-[view]用到你的代码中,你更能够领会
intrinsicContentSize这个属性的含义。控件的内容尺寸可以通过
UIView的
intrinsicContentSize属性来获取的,也可以通过
invalidateIntrinsicContentSize方法来在下次
UI规划事件中重新计算
intrinsicContentSize。直接创建一个原始的UIView对象,显然它的内容尺寸为0。
好了,掌握了这句,如果我需要一个全屏的
view,我该怎么写呢?答案是:
H:|[view]|、
V:|[view]|。
第二句:
H:|-[view]-|和
V:|-15-[view(==30)]
效果如下图:
我想到这里,不用我解释,大家也明白了。我只说下这两句 VFL 语句的含义,第一句上面说过多的就不再讲了,第二句的意思是,给
view添加距离父视图顶部
15 pts的距离,并且设置
view的高度为
30 pts的约束条件。
第三句:
H:|-[view1]-[view2]-[view3(>=50)]-|
前面的都是单个的控件,这次一下给3个控件添加约束条件。解析如下图:
由图我们就可以理解了上面的 VFL 语句的含义了。需要指出的是
[view1]-[view2]-[view3]之间的
-所代表的值并非前面提到的
20 pts,而是
8 pts。前面也提到了,
20 pts是相对于父控件,而同级控件之间的
-表示
8 pts。还有一点是
>=50,我们知道使用
H:时,设置的尺寸是宽度,这里并不是
==50而是
>=50,也就是说
view3的最小宽度为50。
第四句:
H:|-[view2(view1)]和
V:[view1]-[view2(view1)]
这里主要想展示一下怎么设置两个控件等宽等高。解析如图:
当然,如果你不想
view1跟
view2之间有
8 pts的间距,你可以这样写
V:[view1][view2(view1)]。
好了,先写到这里吧。
后记
不知道看到这里,你是否有收获呢?掌握了 VFL 语句的基本语法,那么纯代码实现自动布局也是很简单的。后面若是有时间,我会继续更新内容,欢迎大家继续关注。前面还有一点没有解释,就是 VFL 语句省略
H:也不写
V:的情况。这个其实很简单,不写的话,就代表水平方向
H:。
另外,纯代码书写 AutoLayout 还有一个重要的 API ,如下:
1 2 3 45 | +(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c; |
view1.attr1 = view2.attr2 * multiplier + constant。
本文为转载文章
相关文章推荐
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- 【iOS开发-113】在storyboard上用AutoLayout,纯代码实现AutoLayout布局方法以及简单动画
- iOS 8 Auto Layout界面自动布局系列3-使用代码添加布局约束
- Masonry -- 使用纯代码进行iOS应用的autolayout自适应布局
- ios代码实现Autolayout(自动布局)的简单讲解
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- 【iOS开发-113】在storyboard上用AutoLayout,纯代码实现AutoLayout布局方法以及简单动画
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- 通过代码实现Autolayout自动布局
- Masonry -- 使用纯代码进行iOS应用的autolayout自适应布局
- 使用Auto Layout中的VFL(Visual format language)——代码实现自动布局
- IOS Auto Layout代码实现自动布局--NSLayoutConstraint
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- IOS手动添加的View 在代码中使用(自动布局)autoLayout
- iOS开发笔记--使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- 代码布局Masonry介绍与使用实践(快速上手Autolayout)
- IOS Auto Layout代码实现自动布局--VFL(Visual format language)
- autolayout自动布局代码敲写
- IOS autoLayout之使用VFL语言进行代码自动布局