AutoLayout不管是在StoryBorad还是在xib中都相对来说比较简单,VFL(Visual fromat language)可视化语言基本上用到的比较少,在xCode4时候自动布局的概念还没有,直接使用VFL会很方便,可视化语言依赖于oc运行时创建对应的约束,如果IBOutlet发生改变有的时候会造成莫名其妙的Bug。xCode5之后可视化语言用到的场景相对较少,但是作为一个工作的辅助还是可以稍微了解下。
基础知识
在StotyBoard中添加一个标签一个按钮,不适用自动布局,简单的控制它们之间的水平距离为80,如下图所示:
视图中添加约束:
1
2
|
NSLayoutConstraint
*labelContraint=[
NSLayoutConstraint
constraintWithItem:
self
.changeButton attribute:
NSLayoutAttributeLeft
relatedBy:
NSLayoutRelationEqual
toItem:
self
.descriptionLabel attribute:
NSLayoutAttributeRight
multiplier:1.0 constant:60];
[
self
.view addConstraint:labelContraint];
|
这个只是视图约束的一种方式,下面这种方式才是本文的主角:
1
2
3
4
|
//使用可视化语言添加约束
NSDictionary
*viewDictionary=
NSDictionaryOfVariableBindings
(_descriptionLabel,_changeButton);
NSArray
*visualConstraint=[
NSLayoutConstraint
constraintsWithVisualFormat:@
"[_descriptionLabel]-60-[_changeButton]"
options:0 metrics:
nil
views:viewDictionary];
[
self
.view addConstraints:visualConstraint];
|
这里面用到的constraintsWithVisualFormat方法,具体参数说明如下:
format:参数是vfl语句,语句的基本元素下面会详细解释一下;
opts:枚举参数,默认写0;
metrics:字典,当在format中使用了动态数据,会根据字典去匹配,接下来会具体有例子;
views:字典,传入需要用到的视图集合;
具体format需要参考一下表达式的意思:
水平方向 H:
垂直方向 V:
Views [需要定义的视图]
SuperView |
关系 >=,==,<=
间隙 -
视图内部约束 ()
Demo实战
通过VFL控制手动添加的标签的位置,具体效果如下:
代码实现如下:
1
2
3
4
5
6
7
8
9
10
11
|
UILabel *link=[[UILabel alloc]init];
link.text=@
"http://www.cnblogs.com/xiaofeixiang"
;
link.translatesAutoresizingMaskIntoConstraints=
NO
;
[link setBackgroundColor:[UIColor greenColor]];
[
self
.view addSubview:link];
NSArray
*horizontal=[
NSLayoutConstraint
constraintsWithVisualFormat:@
"H:|-40-[link]-20-|"
options:0 metrics:
nil
views:
NSDictionaryOfVariableBindings
(link)];
NSArray
*vertical=[
NSLayoutConstraint
constraintsWithVisualFormat:@
"V:[_descriptionLabel]-100-[link(>=30)]"
options:0 metrics:
nil
views:
NSDictionaryOfVariableBindings
(link,_descriptionLabel)];
[
self
.view addConstraints:horizontal];
[
self
.view addConstraints:vertical];
|
第一个约束是控制标签距离父视图左右之间的距离,第二个控制标签和”博客园-FlyElephant"之间的垂直距离为100.当然如果你想通过字典控制垂直之间的距离可以按照下面这么做:
1
|
NSArray
*vertical=[
NSLayoutConstraint
constraintsWithVisualFormat:@
"V:[_descriptionLabel]-Vertical-[link(>=30)]"
options:0 metrics:@{@
"Vertical"
:
@200
} views:
NSDictionaryOfVariableBindings
(link,_descriptionLabel)];
|
最后的结果:
友情提示在添加约束的时候不要和StoryBoard中的冲突,如果添加的水平约束StoryBoard中也有的话,就会出现下面这种情况:
1
2
3
4
5
6
7
8
9
10
11
12
|
2015-07-01 10:54:13.537 VFLDemo[2358:60863] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don
't want. Try this: (1) look at each constraint and try to figure out which you don'
t expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you
're seeing NSAutoresizingMaskLayoutConstraints that you don'
t understand, refer to the documentation
for
the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7fc5e3732860 H:[UILabel:0x7fc5e372ef30'\U535a\U5ba2\U56ed-FlyElephant']-(15)-[UIButton:0x7fc5e372d550'\U7fa4:228407086']>"
,
"<NSLayoutConstraint:0x7fc5e37344e0 H:[UILabel:0x7fc5e372ef30'\U535a\U5ba2\U56ed-FlyElephant']-(60)-[UIButton:0x7fc5e372d550'\U7fa4:228407086']>"
)
Will attempt to recover by breaking constraint
<
NSLayoutConstraint
:0x7fc5e37344e0 H:[UILabel:0x7fc5e372ef30
'博客园-FlyElephant'
]-(60)-[UIButton:0x7fc5e372d550
'群:228407086'
]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to
catch
this
in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
|