iOS系统被国内大众广泛熟知,大概是从iphone4开始。在iphone4,iphone4s的时代,屏幕全部是320x480。iOS开发完全不必考虑屏幕的适配,并且当时乔帮主也曾说过,320x480的尺寸有最好的用户体验,iphone将一直延续这个尺寸不变。但是,随着乔帮主的离去,iphone5的问世,打破了这个局面。iOS的开发也面临了屏幕适配的问题。当时最通用的解决方案就是写一个宏来判断当前设备是否是iphone5,如果是,屏幕height就加88。但是后来又有了iphone6,iphone6 plus,再加上各种尺寸的pad,iOS开发需要适配的设备也越来越多。不过还好,AutoLayout自动布局已经日趋完善,完全可以在开发中使用,解决屏幕适配,布局的问题。
AutoLayout使用的方式可以分为三种:
- Interface Builder
- 代码创建单个约束对象
- 可视化格式语言
IB形式就直接拖拖拽拽,操作起来比较快,但是约束多了之后可能显示的比较乱。后两种都是用代码,可以一个一个的创建约束对象再添加的视图上,也可以使用可视化格式语言来一次创建多个约束。三种方式各有利弊,建议根据具体需求,选择配合使用。
我写了一个例子效果如下图,上边是在iphone6模拟器的效果,下边是在iphone4s模拟器的效果。
Interface Builder
最上面的一排粉色的视图是用IB创建并添加约束的,对于使用IB创建约束,除了点击界面上的工具,还可以在Editor菜单下的Align和Pin下创建。
代码创建单个约束
中间一排紫色的视图是用代码创建的单个约束。
//centerView1
UIView* centerView1 = [[UIView alloc] init];
centerView1.backgroundColor = [UIColor purpleColor];
centerView1.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:centerView1];
//left 20
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView1 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:kSuperSpace]];
//centerY = self.view.centerY
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
// width = 181
NSLayoutConstraint* widthConstraint = [NSLayoutConstraint constraintWithItem:centerView1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:181];
widthConstraint.priority = UILayoutPriorityDefaultHigh;
[centerView1 addConstraint:widthConstraint];
//width == height
[centerView1 addConstraint:[NSLayoutConstraint constraintWithItem:centerView1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
//centerView2
UIView* centerView2 = [[UIView alloc] init];
centerView2.translatesAutoresizingMaskIntoConstraints = NO;
centerView2.backgroundColor = [UIColor purpleColor];
[self.view addSubview:centerView2];
// width = centerView1.width
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
// height = centerView1.height
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];
// centerView2 to centerView1 space 8
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView2 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeTrailing multiplier:1 constant:kSpace]];
// centerY = centerView1.centerY
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
//centerView3
UIView* centerView3 = [[UIView alloc] init];
centerView3.translatesAutoresizingMaskIntoConstraints = NO;
centerView3.backgroundColor = [UIColor purpleColor];
[self.view addSubview:centerView3];
// width = centerView1.width
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView3 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
// height = centerView1.height
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView3 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];
// centerView3 to centerView2 space 8
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView3 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:centerView2 attribute:NSLayoutAttributeTrailing multiplier:1 constant:kSpace]];
// centerY = centerView1.centerY
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView3 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:centerView1 attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
// centerView3 Trailing 20
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView3 attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-kSuperSpace]];
可视化格式语言
最下面一排橘黄色视图是用可视化格式语言创建的,显然在代码创建约束中使用可视化格式语言比单个创建约束的代码量要少很多,一个可视化格式语言就可以创建出一组横向的或者纵向的约束。但是也有个别约束是用可视化格式语言无法创建的,比如锁定单个视图的纵横比,这个约束就只能用创建单个约束的方式或者IB的方式来创建。
//bottomView1
UIView* bottomView1 = [[UIView alloc] init];
bottomView1.translatesAutoresizingMaskIntoConstraints = NO;
bottomView1.backgroundColor = [UIColor orangeColor];
[self.view addSubview:bottomView1];
//bottomView2
UIView* bottomView2 = [[UIView alloc] init];
bottomView2.translatesAutoresizingMaskIntoConstraints = NO;
bottomView2.backgroundColor = [UIColor orangeColor];
[self.view addSubview:bottomView2];
//bottomView3
UIView* bottomView3 = [[UIView alloc] init];
bottomView3.translatesAutoresizingMaskIntoConstraints = NO;
bottomView3.backgroundColor = [UIColor orangeColor];
[self.view addSubview:bottomView3];
//height == height
[bottomView1 addConstraint:[NSLayoutConstraint constraintWithItem:bottomView1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomView1 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
[bottomView2 addConstraint:[NSLayoutConstraint constraintWithItem:bottomView2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomView2 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
[bottomView3 addConstraint:[NSLayoutConstraint constraintWithItem:bottomView3 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomView3 attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
//V format
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomView1]-kSuperSpace-|" options:NSLayoutFormatAlignAllBottom metrics:@{@"kSuperSpace" : [NSNumber numberWithInt:kSuperSpace]} views:NSDictionaryOfVariableBindings(bottomView1)]];
//H format
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[bottomView1(181@750)]-[bottomView2(bottomView1)]-[bottomView3(bottomView1)]-|" options:NSLayoutFormatAlignAllBottom metrics:nil views:NSDictionaryOfVariableBindings(bottomView1, bottomView2, bottomView3)]];