使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
使用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
希望对各位读者有所帮助,如果不妥的地方还望指出.
使用Auto Layout中的VFL(Visual format language)--代码实现自动布局的更多相关文章
- 使用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介绍 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:/ ...
随机推荐
- Unity(1) 编辑器结构
5个主要视图视图,未完,持续补充... 1 Project(项目) 用于显示资源 Favorites:按资源分类显示 Assets:按目录结构显示 特殊说明 Prefabs(预设),用于场景中游戏对象 ...
- bzoj 4032: [HEOI2015]最短不公共子串【dp+SAM】
第一.二问: 就是最小的最长公共长度+1,设f[i][j]为a匹配到i,b匹配到j,第一问的转移是f[i][j]=(a[i]==b[j]?f[i-1][j-1]+1:0),第二问的转移是f[i][j] ...
- "字节跳动杯"2018中国大学生程序设计竞赛-女生专场
口算训练 #include <iostream> #include <algorithm> #include <cstring> #include <cstd ...
- swift SqliteDB使用
操作步骤: 1,在 Build Phases -> Link Binary With Libraries 中点击加号,添加 libsqlite3.0.tbd 到项目中来 2,创建连接头文件B ...
- LIS的简单应用:UVA-437
上一次紫芝详细地介绍了动态规划中的经典问题LIS,今天我们抽出一个类似思想的简单题目进行实践练习. The Tower of Babylon(巴比伦塔) Perhaps you have heard ...
- python之模块random,time,os,sys,序列化模块(json,pickle),collection
引入:什么是模块: 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类型. 1.使用python编写的代码(.py ...
- JDBC事务之理论篇
事务: 事务是数据库操作的基本逻辑单位,一般来说,事务总是并发地执行,并且这些事务可能并发地存取相同的数据.因此为了保证数据的完整性和一致性,所有的JDBC相符的驱动程序都必须支持事务管理. 事务可以 ...
- nodejs 学习(1) http与fs
var http=require("http"), fs=require('fs'); var server=http.createServer(function(req,res) ...
- python第一模块数据类型
一·进制之间的转换 十进制转换为二进制:逆序取余法. 二进制转换为十进制:如1101 1*2^0 + 0*2^1 + 1*2^2 +1 十六进制转换为二进制:231 0010 0011 ...
- map中使用await 异步函数
let result=await Promise.all(dataComments.map(async (ele)=>{ return (async ()=>{ let resData= ...