AutoLayout

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算法计算各个子视图的大小和位置,算出来后将子视图的framelayout 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。