使用Auto Layout中的VFL(Visual format language)--代码实现自动布局【转】
本文将通过简单的UI来说明如何用VFL来实现自动布局。在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI。
一:API介绍
NSLayoutConstraint API
|
1
2
3
4
|
NSLayoutConstraint+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)optsmetrics:(NSDictionary *)metricsviews:(NSDictionary *)views; |
参数介绍:
format:此参数为你的vfl语句,比如:@"H:|-[button]-|"
opts:枚举参数,默认写0,具体跟据你所实现的需求去选择你想要的枚举
metrics:这里是一个字典,当在format中使用了动态数据比如上现这句:@"H:|-[button(==width)]-|",表示这个button的宽度为width,那么这个参数去哪里找呢?就是在这个字典里面找到key对就的值,如果没有找到这个值,app就会crash.
views:顾名思义,这是传所有你在vfl中使用到的view,那在上面这句例子中的应该怎么传呢?结果是这样的:NSDictionaryOfVariableBindings(button).如果你使用到了多个view,就可以这样NSDictionaryOfVariableBindings(button,button1,button3...),这个名字也要跟参数format中的一一对应,缺一不可.
2.UIView API
|
1
2
|
UIView- (void)addConstraints:(NSArray *)constraints; |
在上面1中返回值类型是NSArray,而现在这个方法的参数也刚好是一个NSArray类型。那么直接把上一个方法的返回值当作这个方法的参数就可以了。如果你有多个VFL,你也可以利用可变数组( NSMutableArray)把这多个VFL返回的数据拼在一起,然后再调用addConstraints:方法。
二:简单的使用
1.单控件的使用(没有与其他控制有关联,比如空隙等)
新建一个单页面项目Single View Application),在项目里面加上下面这段代码代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "ViewController.h"@interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIButton *button=[[UIButton alloc]init]; [button setTitle:@"点击一下" forState:UIControlStateNormal]; button.translatesAutoresizingMaskIntoConstraints=NO; [button setBackgroundColor:[UIColor blackColor]]; [self.view addSubview:button]; NSArray *constraints1=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]; NSArray *constraints2=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[button(==30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]; [self.view addConstraints:constraints1]; [self.view addConstraints:constraints2]; } @end |
运行程序,效果图如下:

可以看到,我们新建的button已经出来,证明上面的自动布局语句(VFL)已经生效。那么我们来详细看看这些语句的意义是什么。
|
1
2
3
4
|
NSArray *constraints1=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]; |
这里的意思是:button在水平方向上距离它的superView,左右各20px,比如在这里他的大小就是320-20*2=280.在@"H:|-[button]-|"这个语句中,其中"H:"是表示这是水平方向上的约束,"|"是表示superView,"-"表示一个间隔空间,这个间隔如果是如superView之间的,那么就是20px,如果是两个同级别的view,比如@"[button]-[button1]",那么这里表示的是8px.
|
1
2
3
4
|
NSArray *constraints2=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[button(==30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]; |
跟上面有点不同,@"V:|-20-[button(==30)]",其中"V:"中代表这是垂直方向上的约束,"|-20-"这里的意思就是距离头部为20px,相当于y坐标为20。后面的"[button(==30)]",是指定这个button的高度为30px.y坐标固定了,高度固定了,那这个view的约束就完成了。如果你有需要,你的高度值(或者其他同类型的)可以使用>=,==,<=来表示,甚至你可以组合来用,像上面的30,你可以指定一个区别,比如:(>=30,<=40),这同样也是可以的。如果你想表达他的优先级别,可以使用@"V:|-20-[button(==30@1000)]",这个@1000,就是他的级别了。你可以适配XIB或者SB对它的优先级做更多的处理.
PS:值得注意的是,在用代码创建的UIView在,一定要加上下面这句代码
|
1
|
button.translatesAutoresizingMaskIntoConstraints=NO; |
如果没有上面这一行,你的约束将不生效,控制台会输出一连串的错误.
2:多控件之间关联使用
基于上面的代码上,我们重新加了一段代码,现在的全部代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#import "ViewController.h"@interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIButton *button=[[UIButton alloc]init]; [button setTitle:@"点击一下" forState:UIControlStateNormal]; button.translatesAutoresizingMaskIntoConstraints=NO; [button setBackgroundColor:[UIColor blackColor]]; [self.view addSubview:button]; NSArray *constraints1=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]; NSArray *constraints2=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[button(==30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]; [self.view addConstraints:constraints1]; [self.view addConstraints:constraints2]; UIButton *button1=[[UIButton alloc]init]; button1.translatesAutoresizingMaskIntoConstraints=NO; [button1 setTitle:@"请不要点击我" forState:UIControlStateNormal]; [button1 setBackgroundColor:[UIColor redColor]]; [self.view addSubview:button1]; NSArray *constraints3=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button1]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button1)]; NSArray *constraints4=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-[button1(==30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button1,button)]; [self.view addConstraints:constraints3]; [self.view addConstraints:constraints4]; } |
运行的效果图如下:

通过代码对比,可以看出,在button1的垂直方向约束上,我们做了一点改变。水平方向上跟button一样,这里就不多作解释。我们来看看垂直方向上的。
|
1
2
3
4
|
NSArray *constraints4=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-[button1(==30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button1,button)]; |
VFL语句为:@"V:[button]-[button1(==30)]",这里用到了两个view在VFL语句里面。刚才我们也说到,"-"在同一级别的View上使用的时候表示的间距为8个像素点,整一句的意思就是button1的y坐标离button有8个像素点.在不使用auto layout的时候,可以这样表达CGRectGetMaxY(button.frame)+8.
我再改一下上面这一句VFL
|
1
2
3
4
|
NSArray *constraints4=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-[button1(==height)]" options:0 metrics:@{@"height":@30} views:NSDictionaryOfVariableBindings(button1,button)]; |
再次运行,你会发现,效果是一样的。这样你就知道怎么动态去给view加上高度或者宽度,或是其他间距了吧?
那么,如何做到两个View,或是多个View之间等高,或者等宽呢?能用VFL可以做到吗?除了通过上面的直接赋值宽高的数值外,VFL还提供了另外一种写法用于等宽等高上。
还是上面的Demo,我们改一下代码
|
1
2
3
4
5
6
7
8
9
|
NSArray *constraints3=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button1(button)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button1,button)]; NSArray *constraints4=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-[button1(button)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button1,button)]; |
通过@"H:|-[button1(button)]",@"V:[button]-[button1(button)]",这两句就可以轻松实现等宽等高了!
三:最后对格式的字符串作一个总结介绍
功能 表达式
水平方向 H:
垂直方向 V:
Views [view]
SuperView |
关系 >=,==,<=
空间,间隙 -
优先级 @value
NSLayoutFormatDirectionLeadingToTrailing 怎么理解?
NSLayoutFormatDirectionLeadingToTrailing
Arrange objects in order based on the normal text flow for the current user interface language. In English this results in the first object being placed farthest to the left, the next one to its right, and so on. In right to left languages this ordering is reversed.
意思就是默认的排版方式,就是从左往右看,从上往下看。
于是就引出了:
NSLayoutFormatDirectionLeftToRight 与 NSLayoutFormatDirectionRightToLeft
也不难理解,前一个是从屏幕左沿布局开始算起,后一个是从屏幕右沿开始算起。
使用Auto Layout中的VFL(Visual format language)--代码实现自动布局【转】的更多相关文章
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
使用Auto Layout中的VFL(Visual format language)--代码实现自动布局 2014-12-09 10:56 编辑: zhiwupei 分类:iOS开发 来源:机智的新手 ...
- 转载自@机智的新手:使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
本文将通过简单的UI来说明如何用VFL来实现自动布局.在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI. 一:API介绍 NSLayoutConstraint API 1 2 3 ...
- 【转】使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
本文将通过简单的UI来说明如何用VFL来实现自动布局.在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI. 一:API介绍 NSLayoutConstraint API 1 2 3 ...
- 转载:使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
本文将通过简单的UI来说明如何用VFL来实现自动布局.在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI. 一:API介绍 NSLayoutConstraint API 1 2 3 ...
- 使用Auto Layout中的VFL(Visual format language)——代码实现自动布局
本文将通过简单的UI来说明如何用VFL来实现自动布局.在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI. 一:api介绍 1.NSLayoutConstraint API NSL ...
- IOS使用Auto Layout中的VFL适配
做登录页面,之前做都是用frame做,今天想着用Auto Layout中的VFL来做.觉得做的效果还是可以的(自恋一下下). 首先看下效果图和标记图 自己在做的过程中也遇到了好多问题,不过也一个一个的 ...
- iOS开发-VFL(Visual format language)和Autolayout
AutoLayout不管是在StoryBorad还是在xib中都相对来说比较简单,VFL(Visual fromat language)可视化语言基本上用到的比较少,在xCode4时候自动布局的概 ...
- Visual format language
所谓的VFL语言其实就是Visual format language 的缩写,是一种使用代码添加约束的方式,类似于Masonry SDAutolayout的效果,但是操作起来可能要相对简单.一行代码 ...
- IOS使用 Visual Format Language 定义水平和垂直约束
定义限制条件来改变一个 UI 组件在其父视图的水平和垂直方向布局的方法. 可以使用方程式里 H:方向符号代表水平方向的边距,使用 V:方向符号代表垂直方向的边 距. 转载请注明,本文转自:http:/ ...
随机推荐
- WCF 断点不会命中
VS的调试模式改为Debug 工具—选项—调试—常规中的‘要求源文件和原始版本完全匹配’的勾去掉
- Cache-control使用Cache-control:private学习笔记
其作用根据不同的重新浏览方式,分为以下几种情况:(1).打开新窗口值为private.no-cache.must-revalidate,那么打开新窗口访问时都会重新访问服务器.而如果指定了max-ag ...
- Java中面向对象的详解
1:成员变量和局部变量的区别(理解) (1)在类中的位置不同 成员变量:类中方法外 局部变量:方法定义中或者方法声明上 (2)在内存中的位置不同 成员变量:在堆中 局部变量:在栈中 (3)生命周期不同 ...
- 关于工伤事故索赔计算很好用的一款APP
关于工伤事故索赔计算很好用的一款APP.详细介绍工伤伤残等级评估 工伤计算器根据国家颁布<劳动能力鉴定 职工工伤与职业病致残等级>,通过关键字检索,快速评估工伤伤残等级. 软件说明: 1 ...
- 简单poi读取excel
1.添加依赖jar包 maven配置: <!-- poi being --> <dependency> <groupId>org.apache.poi</gr ...
- mysql常用&实用语句
Mysql是最流行的关系型数据库管理系统,也是目前最常用的数据库之一,掌握其常用的操作语句是必不可少的. 下面是自己总结的mysqp常用&实用的sql语句: 1.mysql -u root - ...
- 神奇的盒模型(BFC)
上一篇我提到每一个元素都有自己的display属性,其属性值可以改变.其改变的方式,可以利用神奇的css盒模型(BFC). 盒模型,是css可视化格式化系统的基础,可以用于元素定位和网页布局.一个盒模 ...
- 第七课 第二节,T语言流程语句(版本5.0)
while语句 循环结构是程序中一种很重要的结构其特点是,在给定条件成立时,反复执行某程序段,直到条件不成立为止给定的条件称为循环条件,反复执行的程序段称为循环体 (注:关键字,while,end) ...
- ✡ leetcode 166. Fraction to Recurring Decimal 分数转换 --------- java
Given two integers representing the numerator and denominator of a fraction, return the fraction in ...
- sed命令的基本使用
sed(Stream Editor):流编辑器 一次只读取一行 模式空间 1.sed语法: sed [option] "script" FILE... 2.选项: -n:静默模式, ...