手写代码自动实现自动布局,即Auto Layout的使用,有需要的朋友可以参考下。
这里要注意几点:
- 对子视图的约束,若是基于父视图,要通过父视图去添加约束。
-
对子视图进行自动布局调整,首先对UIView的一个属性设置,这是因为如果我们用Interface Builder,勾选Ues Autolayout,这时autoresizingMask就会被Auto Layout 取代,在手写代码时,我们就需要手动控制,代码如下
[_shadow setTranslatesAutoresizingMaskIntoConstraints:NO]
- 在添加约束前,要先将子视图添加到父视图上。
以下为例,oneImgView 上添加子视图shadow,对shadow进行约束
@property (nonatomic, strong) UIImageView *shadow; @property (nonatomic, strong) UIImageView *oneImgView; [_shadow setTranslatesAutoresizingMaskIntoConstraints:NO]; // 使用自动布局 [self.oneImgView addSubview:_shadow]; // 添加约束前要先将子视图添加到父视图上 NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_shadow attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.oneImgView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]; [self.oneImgView addConstraint:constraint]; constraint = [ NSLayoutConstraint constraintWithItem:_shadow attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.oneImgView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f ]; [self.oneImgView addConstraint:constraint]; constraint = [ NSLayoutConstraint constraintWithItem:_shadow attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0f constant:58.0f ]; [self.oneImgView addConstraint:constraint]; constraint = [ NSLayoutConstraint constraintWithItem:_shadow attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.oneImgView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f ]; [self.oneImgView addConstraint:constraint];
关于函数
+(instancetype)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation
toItem:(id)view2 attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier constant:(CGFloat)c;
苹果的官方文档是这么描述的。
/* Create constraints explicitly. Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant"
If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.
*/
所以你只需要记住view1.attr1 = view2.attr2 * multiplier + constant就可以了
可视化格式语言约束(VFL)
除此之外iOS 8推出了一种新的约束方式——可视化格式语言约束,这种约束方式和中国古代的象形文字很相似。它可以一次添加多个约束,而且很直观,但不是所有的约束都可以满足的,维护也有一定的难度
代码为例,如果我要实现shadow 距离父视图左边界为20,宽为40,距离顶部20,高度最小30,不能超过100
NSArray *constraints = nil; constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_shadow(==40)]|" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(_shadow)]; [self.oneImgView addConstraints:constraints]; constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[_shadow(>=58)@100]" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(_shadow)]; [self.oneImgView addConstraints:constraints];
- format:这里是你的VFL语句,比如:@”H:|[_shadow]|”(注意“-”默认父子视图之间表示20px,同级视图之间表示8px,但是如果是“-10-”则表示前后相距10,短线距离忽略)
- options:默认写0,跟据需求去选择你想要的枚举
- metrics:
字典,
你的VFL语句中使用了动态参数时,将参数名和对应的值为键值对写在字典中,比如:@”H:|-[_shadow(==width)]-|”,表示这个
_shadow的宽度为width,这是字典里面找到key对就的值,如果没有找到这个值,app就会crash.
- views:字典,你的VLF语句中使用到得所有view,用这个宏去添加NSDictionaryOfVariableBindings(view1,view2,view3…)
上面代码中VFL语句为:@”H:|[_shadow]|”,其中“|”表示父视图的边界
|: 表示父视图
-:表示距离
V: :表示垂直
H: :表示水平
>= :表示视图间距、宽度和高度必须大于或等于某个值
<= :表示视图间距、宽度和高度必须小宇或等于某个值
== :表示视图间距、宽度或者高度必须等于某个值
@ :>=、<=、== 限制 最大为 1000
以下为例
|-[view]-|: 视图处在父视图的左右边缘内
|-[view] : 视图处在父视图的左边缘
|[view] : 视图和父视图左边对齐
-[view]- : 设置视图的宽度高度
|-30.0-[view]-30.0-|: 表示离父视图 左右间距 30
[view(200.0)] : 表示视图宽度为 200.0
|-[view(view1)]-[view1]-| :表示视图宽度一样,并且在父视图左右边缘内
V:|-[view(50.0)] : 视图高度为 50
V:|-(==padding)-[imageView]->=0-[button]-(==padding)-| : 表示到父视图左边的距离为Padding,这两个视图间距必须大于或等于0并且距离底部父视图为 padding。
[wideView(>[email protected])] :视图的宽度为至少为60 不能超过 700
如果没有声明方向默认为 水平 V: