美文网首页
AutoLayout

AutoLayout

作者: 得_道 | 来源:发表于2020-10-26 21:37 被阅读0次

    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

    相关文章

      网友评论

          本文标题:AutoLayout

          本文链接:https://www.haomeiwen.com/subject/mgaamktx.html