Auto Layout
是由苹果公司UIKit框架提供的一个用于动态计算UIView
及其子类的大小和位置的库。
Cassowary算法
说到Auto Layout
就不得不说Cassowary
算法,因为Auto Layout
是构建在Cassowary
算法的基础之上的。1997年,Auto Layout
用到的布局算法论文发表,被称为高效的线性方程求解算法。2011年苹果利用Cassowary
算法为开发者提供了Auto Layout
自动布局库中。由于Cassowary
算法的本身的优秀,不仅是苹果公司,许多开发者将其运用到各个不同的开发语言中,如JavaScript、ASP.NET、Java、C++等都有运用Cassowary
算法的库。从这里也可以看出Cassowary
算法自身的优秀和先进性,不然不会被运用的如此广泛。
Auto Layout的生命周期
苹果的Auto Layout
是基于Cassowary算法的,苹果在此基础上提供了一套Layout Engine
引擎,由它来管理页面的布局,来完成创建、更新、销毁等。
在APP启动后,会开启一个常驻线程来监听约束变化,当约束发生变化后会出发Deffered Layout Pass
(延迟布局传递),在里面做容错处理(如有些视图在更新约束时没有确定或缺失布局申明),完成后进入约束监听变化的状态。
当下一次刷新视图(如调用layoutIfNeeded()
)时,Layout Engine
会从上到下调用layoutSubviews()
,然后通过Cassowary
算法计算各个子视图的大小和位置,算出来后将子视图的frame
从layout Engine
里拷贝出来,在之后的处理就和手写frame的绘制、渲染的过程一样了。使用Auto Layout
和手写frame
多的工作就在布局计算上。
NSLayoutConstraint
iOS 6提供的NSLayoutConstraint语法添加约束
centerView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *consW = [NSLayoutConstraint constraintWithItem:centerView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:0
constant:120.0
];
NSLayoutConstraint *consH = [NSLayoutConstraint constraintWithItem:centerView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view attribute:NSLayoutAttributeHeight
multiplier:0
constant:120.0
];
NSLayoutConstraint *consX = [NSLayoutConstraint constraintWithItem:centerView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0
];
NSLayoutConstraint *consY = [NSLayoutConstraint constraintWithItem:centerView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0
];
[self.view addConstraints:@[consW,consH,consX,consY]];
VFL语法
centerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[centerView(120)]" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[centerView(120)]" options:0 metrics:nil views:views]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
NSLayoutAnchor
使用iOS 9之后Apple提供的NSLayoutAnchor
let centerView:UIView = UIView.init()
view.addSubview(centerView)
centerView.backgroundColor = UIColor.red
centerView.translatesAutoresizingMaskIntoConstraints = false
centerView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
centerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
centerView.widthAnchor.constraint(equalToConstant: 120).isActive = true
centerView.heightAnchor.constraint(equalToConstant: 120).isActive = true
NSLayoutAnchor常用属性
leadingAnchor
trailingAnchor
leftAnchor
rightAnchor
topAnchor
bottomAnchor
widthAnchor
heightAnchor
centerXAnchor
centerYAnchor
firstBaselineAnchor
lastBaselineAnchor
写在最后
使用NSLayoutConstraint语法和VFL语法是最复杂的,尤其是NSLayoutConstraint语法要用30多行代码才能是想同样的效果,代码行数越多出错的概率也就成正比上升,
如果你的App
要兼容iOS 9
以下的各个版本,建议使用Masonry,如果只兼容iOS 9以上的版本,建议使用SnapKit或者系统提供的NSLayoutAnchor API,毕竟Masonry
这个库已经2年没有更新了。
在这里我推荐优先使用NSLayoutAnchor