iOS自动布局(代码实现)

官方API

涉及的约束类:NSLayoutConstraint

#NOTE:
使用autoLayout前,需将视图的
setTranslatesAutoresizingMaskIntoConstraints属性设为NO(默认为YES),如名字所示,如果为YES,运行时系统会自动将Autoresizing Mask转换为constraints,而这些约束和自己添加的约束会产生冲突

添加约束
一个NSLayoutConstraint实例对应一条约束

+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

意思是:view1的某个属性(attr1)等于view2的某个属性(attr2)的值的多少倍(multiplier)加上某个常量(constant)。描述的是一个view与另外一个view的位置和大小约束关系。其中属性attribute有上、下、左、右、宽、高等,关系relation有小于等于、等于、大于等于。需要注意的是,小于等于 或 大于等于 优先会使用 等于 关系,如果 等于 不能满足,才会使用 小于 或 大于。例如设置一个 大于等于100 的关系,默认会是 100,当视图被拉伸时,100 无法被满足,尺寸才会变得更大。

示例1:

目的:子视图(subview)的上下左右边缘都离父视图的边缘100个像素

//创建子view
UIView *subView = [[UIView alloc] init];
[subView setBackgroundColor:[UIColor blackColor]];
//将子view添加到父视图上
[self.view addSubview:subView];
//使用Auto Layout约束,禁止将Autoresizing Mask转换为约束
[subView setTranslatesAutoresizingMaskIntoConstraints:NO];
//layout 子view
//子view的上边缘离父view的上边缘100个像素
NSLayoutConstraint *contraint1 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:100.0];
//子view的左边缘离父view的左边缘100个像素
NSLayoutConstraint *contraint2 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:100.0];
//子view的下边缘离父view的下边缘100个像素
NSLayoutConstraint *contraint3 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-100.0];
//子view的右边缘离父view的右边缘100个像素
NSLayoutConstraint *contraint4 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-100.0];
//把约束添加到父视图上
NSArray *array = [NSArray arrayWithObjects:contraint1, contraint2, contraint3, contraint4, nil nil];
[self.view addConstraints:array];

NOTE:
1、添加约束前确定已经把需要布局的子view添加到父view上了
2、要把子视图的约束加在父视图上
3、iOS中原点在左上角,所以使用offset时注意right和bottom用负数

示例二:

目的:子视图(subview)在父视图的中间,且子视图长300,高200。

//创建子view
UIView *subView = [[UIView alloc] init];
[subView setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:subView];
//使用Auto Layout约束,禁止将Autoresizing Mask转换为约束
[subView setTranslatesAutoresizingMaskIntoConstraints:NO];
//layout 子view
//子view的中心横坐标等于父view的中心横坐标
NSLayoutConstraint *constrant1 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
//子view的中心纵坐标等于父view的中心纵坐标
NSLayoutConstraint *constrant2 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0];
//子view的宽度为300
NSLayoutConstraint *constrant3 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:300.0];
//子view的高度为200
NSLayoutConstraint *constrant4 = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:200.0];
//把约束添加到父视图上
NSArray *array = [NSArray arrayWithObjects:constrant1, constrant2, constrant3, constrant4, nil nil];
[self.view addConstraints:array];

NOTE:
1、如果是设置view自身的属性,不涉及到与其他view的位置约束关系。比如view自身的宽、高等约束时,方法constraintWithItem:的第四个参数view2(secondItem)应设为
nil;且第五个参数attr2(secondAttribute)应设为 NSLayoutAttributeNotAnAttribute 。
2、在设置宽和高这两个约束时,relatedBy参数使用的是 NSLayoutRelationGreaterThanOrEqual,而不是 NSLayoutRelationEqual。因为 Auto Layout 是相对布局,所以通常你不应该直接设置宽度和高度这种固定不变的值,除非你很确定视图的宽度或高度需要保持不变。

更改约束
只能修改常量constant值
步骤:先遍历,根据标识字段判断,找到后修改
示例:

NSArray *constrains = self.view.constraints;
for (NSLayoutConstraint* constraint in constrains) {
if (constraint.firstAttribute == NSLayoutAttributeTop) {
constraint.constant = 10;
}
}

方法函数:
setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。

layoutIfNeeded:告知页面布局立刻更新(一般都会和
setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。)

layoutSubviews:系统重写布局。

setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始。

updateConstraintsIfNeeded:告知立刻更新约束。

updateConstraints:系统更新约束。

others

利用AutoLayout实现动画
示例:

//start animations
//先根据初始化添加的约束生成最初的frame并显示view
[self.view layoutIfNeeded];
[UIView animateWithDuration:3.0 animations:^{
//遍历查找view的heigh约束,并修改它
NSArray *constrains = self.view.constraints;
for (NSLayoutConstraint* constraint in constrains) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = 300;
}
}
//更新约束  在某个时刻约束会被还原成frame使视图显示
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];

三方框架三方库

常用:
Masonry:(https://github.com/SnapKit/Masonry
ALView+PureLayout(https://github.com/smileyborg/PureLayout)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值