iOS 之Autolayout使用经验总结
Autolayout是iOS6以后才出现的新技术,比frame使用更加地方便,比Autoresizing更加地强大。下面,就介绍一下在项目开发中使用Autolayout几种途径。
纯代码实现Autolayout
1.NSLayoutConstraint
[NSLayoutConstraint constraintWithItem:(id)item attribute:(NSLayoutAttribute)attribute relatedBy:(NSLayoutRelation)relation toItem:(id)otherItem attribute:(NSLayoutAttribute)otherAttribute multiplier:(CGFloat)multiplier constant:(CGFloat)constant]
举个简单的例子,我们在所在controller默认view上添加一个子视图subview,subview的宽高为view宽高的1/3,距离view左边100,距离view上边150,就可以用下面代码这样实现:
UIView *subView = [[UIView alloc]init];
subView.backgroundColor = [UIColor greenColor];
[self.view addSubview:subView];
subView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1. constant:150]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.3 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.3 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1. constant:100]];
运行结果:
实例1.png
上面方法参数说明:
第一个参数:指定约束左边的视图view1
第二个参数:指定view1的属性attr1
第三个参数:指定左右两边的视图的关系relation
第四个参数:指定约束右边的视图view2
第五个参数:指定view2的属性attr2
第六个参数:指定一个与view2属性相乘的乘数multiplier
第七个参数:指定一个与view2属性相加的浮点数constant
依据的公式是:view1.attr1 = view2.attr2*multiplier +constant
NSLayoutAttribute的类型:
NSLayoutAttributeLeft
视图的左边
NSLayoutAttributeRight
视图的右边
NSLayoutAttributeTop
视图的上边
NSLayoutAttributeBottom
视图的下边
NSLayoutAttributeLeading
视图的前边
NSLayoutAttributeTrailing
视图的后边
NSLayoutAttributeWidth
视图的宽度
NSLayoutAttributeHeight
视图的高度
NSLayoutAttributeCenterX
视图的中点的X值
NSLayoutAttributeCenterY
视图中点的Y值
NSLayoutAttributeBaseline
视图的基准线
NSLayoutAttributeNotAnAttribute
无属性
NSLayoutRelation的类型:
NSLayoutRelationLessThanOrEqual
关系小于或等于
NSLayoutRelationEqual
视图关系等于
NSLayoutRelationGreaterThanOrEqual
视图关系大于或等于
这里要说明一下,设置约束之前必须要求确保子视图添加到了父视图上了(如:[self.view addSubview:subView]
),并且被约束的视图的translatesAutoresizingMaskIntoConstraints = NO
,不然就会发生程序crash。
1.1 VFL(Visual format language)
VFL是NSLayoutConstraint使用特定的NSString类型字符串来创建Constraint,通过下面方法就可以创建
[NSLayoutConstraint
constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views]
关于VFL格式使用规则,可以参考这篇博客http://blog.csdn.net/mmoaay/article/details/46707103
2.Masonry
通过上面的NSLayoutConstraint使用可以发现,每次添加一条约束就要写一长串的代码,如果视图约束很多的话,那么就要写很多的代码,所以就有人基于NSLayoutConstraints进行了封装。Masonry就是基于NSLayoutConstraints封装的轻量级的第三方开源框架之一。所以实例1.png
可以通过Masonry实现:
UIView *subView = [[UIView alloc]init];
subView.backgroundColor = [UIColor greenColor];
[self.view addSubview:subView];
__weak typeof(self) weakSelf = self;
[subView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(@100);
make.top.mas_equalTo(@150);
make.width.mas_equalTo(weakSelf.view.mas_width).multipliedBy(0.3);
make.height.mas_equalTo(weakSelf.view.mas_height).multipliedBy(0.3);
}];
xib 中Autolayout设置
在xib中使用Autolayout,是一种非常直观,非常方便的一种方式。我们可以在不用代码就可以实现各种布局。
实例2.gif
按照图中所示,可以很快的设置子视图Top,Leading,Bottom,Trailing的约束,切换到导航栏Show the size inspect按钮可以看到已经设置好的各个约束,并且可以对设置好约束进行修改,如修改每个约束中constant,priority,multiplier值等。
当然,不管是纯代码还是xib实现Autolayout,都可能遇到约束冲突的情况。比如,一个subview子视图基于父视图设置了Top,Leading,Bottom,Trailing四个约束,并且又设置了subview的高度height,这样运行就是出现Probably at least one of the constraints in the following list is one you don't want.
的警告,因为subview子视图高度height约束和Top或Bottom产生了冲突。
约束冲突可以通过修改Autolayout约束的优先级不同的方式进行解决,在Autolayout中每个约束都有一个优先级priority,priority的范围是1 ~ 1000,默认创建的约束priority最高是1000,并且系统默认提供了Required(1000)、High(750)、Low(250)三种priority。所以对于上述subview子视图产生的约束冲突问题,可以通过修改subview 子视图Top或Bottom约束的priority小于1000就可以解决冲突问题。
小结
以上介绍了Autolayout几种使用的途径。其实,每种途径都有很多的内容,这里对每种途径只是简单的说明了一下,具体使用Autolayout哪种途径,还需要根据自己的项目情况及自己掌握程度而定。