随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享。
什么是Auto Layout?
Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应。
为什么要用Auto Layout?
Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题。
在iPhone4时代开发者只需要适配一种屏幕尺寸,相比与Android阵营的相对布局,iOS开发者们最长用的做法是使用绝对布局,坐标和大小只要写死就ok了。随后iPhone5出了,对于两种屏幕尺寸,就需要考虑一个新的问题,屏幕适配。苹果其实很早就考虑到了这一点Autoresizing技术,诚然Autoresizing有所不足,苹果在iOS6发布后引入了Autolayout特性,适应更广泛场景下的布局需求。当然了iPhone5由于和iPhone4在屏幕宽度上一致,即便不用上这些技术适配起来也不麻烦(笔者再之前也只用到了Autoresizing),不过在iPhone6即将推出,即将面临更复杂的屏幕适配时,Auto Layout能帮助我们很好地解决这个问题,此外也能解决横屏竖屏切换,iPad的适配问题。
下面是本文事例代码在横竖屏切换下的效果:
如何使用Auto Layout?
Auto Layout的基本概念
Auto Layout的核心是约束(constraint),通过对view的约束(view的大小,view与view之间的关系)使得view能够自己计算出尺寸和坐标。
Visual Format Language,在Auto Layout中使用的形象描述约束的一种语言规则。
Auto Layout的使用还是比较复杂的,一开始用可能会感觉云里雾里的,用的多了习惯VFL的写法之后就会感觉到它的方便了。
在代码中使用Auto Layout
01.
- (
void
)viewDidLoad
02.
{
03.
[
super
viewDidLoad];
04.
05.
self.view.backgroundColor = [UIColor greenColor];
06.
UIView *viewTopLeft = [[UIView alloc] init];
07.
UIView *viewTopRight = [[UIView alloc] init];
08.
UIView *viewBottom = [[UIView alloc] init];
09.
[viewTopLeft setBackgroundColor:[UIColor blueColor]];
10.
[viewTopRight setBackgroundColor:[UIColor redColor]];
11.
[viewBottom setBackgroundColor:[UIColor blackColor]];
12.
13.
//添加约束之前必须讲view添加到superview里
14.
[self.view addSubview:viewTopRight];
15.
[self.view addSubview:viewTopLeft];
16.
[self.view addSubview:viewBottom];
17.
18.
//对于要使用Auto Layout的控件需要关闭Autoresizing
19.
[viewTopLeft setTranslatesAutoresizingMaskIntoConstraints:NO];
20.
[viewTopRight setTranslatesAutoresizingMaskIntoConstraints:NO];
21.
[viewBottom setTranslatesAutoresizingMaskIntoConstraints:NO];
22.
23.
//使用VFL
24.
#
if
1
25.
26.
//dict和metrics相当于vfl中的名称与对象和数值的映射
27.
NSDictionary *dict = NSDictionaryOfVariableBindings(viewTopLeft, viewTopRight, viewBottom);
28.
//相当于这么写 NSDictionary *dict = @[@"viewTopLeft":viewTopLeft, @"viewTopRight":viewTopRight, @"viewBottom",viewBottom];不一定名称要与对象名一致
29.
NSDictionary *metrics = @{@
"pad"
:
@10
};
30.
31.
//水平关系(H:,可省略如vfl1),"|"相当与superview,"-"是连接符,表示两者间的间距也可以没有表示无间距
32.
//转化正自然语言的描述就是:superview的左边界间隔pad距离是viewTopLeft(宽度与viewTopRight相等)再间隔默认距离是viewTopRight再间隔10的距离是superview的右边界。
33.
NSString *vfl0 = @
"H:|-pad-[viewTopLeft(==viewTopRight)]-[viewTopRight]-10-|"
;
34.
NSString *vfl1 = @
"|[viewBottom]|"
;
35.
36.
//垂直关系(V:)
37.
NSString *vfl2 = @
"V:|-[viewTopLeft(==viewBottom)]-[viewBottom]-pad-|"
;
38.
NSString *vfl3 = @
"V:|-[viewTopRight]-[viewBottom]-pad-|"
;
39.
40.
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl0 options:
0
metrics:metrics views:dict]];
41.
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl1 options:
0
metrics:metrics views:dict]];
42.
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:
0
metrics:metrics views:dict]];
43.
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl3 options:
0
metrics:metrics views:dict]];
44.
45.
//不使用VFL
46.
#
else
47.
//viewTopLeft的leading与其superview的leading(左侧)对齐
48.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeLeading multiplier:
1
constant:-
10
]];
49.
50.
//viewTopLeft的top与其superview的top对齐
51.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeTop multiplier:
1
constant:-
10
]];
52.
53.
//viewTopRight的top与viewTopLeft的top对齐
54.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeTop multiplier:
1
constant:
0
]];
55.
56.
//viewTopRight的leading与viewTopLeft的trailing(右侧)对齐
57.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeTrailing multiplier:
1
constant:
10
]];
58.
59.
//viewTopRight的trailing与其superview的右侧对其
60.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:
1
constant:-
10
]];
61.
62.
//viewTopRight的宽与viewTopLeft宽相等
63.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeWidth multiplier:
1
constant:
0
]];
64.
65.
//viewTopRight的高与viewTopLeft高相等
66.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopLeft attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:viewTopRight attribute:NSLayoutAttributeHeight multiplier:
1
constant:
0
]];
67.
68.
//viewBottom的top与viewTopRight的bottom对齐
69.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:viewTopRight attribute:NSLayoutAttributeBottom multiplier:
1
constant:
10
]];
70.
71.
//viewBottom的bottom与superview的bottom对齐
72.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:
1
constant:-
10
]];
73.
74.
//viewBottom的leading与viewTopLeft的leading对齐
75.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeLeading multiplier:
1
constant:
0
]];
76.
77.
//viewBottom的高与viewTopLeft的高相等
78.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeHeight multiplier:
1
constant:
0
]];
79.
80.
//viewBottom的宽与其superview的高相等
81.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:
1
constant:-
20
]];
82.
83.
#endif
84.
85.
//更新约束
86.
[self.view setNeedsUpdateConstraints];
87.
[self.view updateConstraintsIfNeeded];
88.
}</span>
注意点:
1.约束必须有给定的size然后通过约束计算出各个view的size和位置,上面self.view的size是给定的,如果superview的size不固定则必须给定某个subview的size才能通过约束计算出其他的。
2.两个view之间的约束应该放在他们superview上,如果一个view是superview只要放在superview的那个上就行了。
2.约束的设计最好不要冲突,虽然可以设置优先级,但是容易出问题。
3.VFL方式的设置view的size时只有相等,小等或大等3种关系,没法像使用方法生成约束那样可以设置两个view的比例,所以在具体的应用中还是要两者结合起来使用。