美文网首页
Auto Layout Animation

Auto Layout Animation

作者: 阿朱先生 | 来源:发表于2018-11-17 14:15 被阅读0次

    Chapter 6, Introduction to Auto Layout

    主要介绍一些基本的auto layout布局,没什么好说的。

    Chapter 7, Animating Constraints

    本章主要是介绍如果对约束添加动画。和普通的对UIView属性做动画不同,对约束的动画经常是创建一个新的约束替换老的约束,然后让Auto Layout在两个约束间做动画。

    1 动态改变布局

    假如存在一个高度的约束

        @IBOutlet weak var someViewHeightConstraint: NSLayoutConstraint!
    

    现在需要对高度做动画,更改为高度为 200
    代码如下:

        someViewHeightConstraint.constant = 200
    

    如果只是单纯的执行上面的代码,视图的高度会变成200,但是不会有动画效果。此时需要调用 layoutIfNeeded() 方法,因为当改变约束constant变量的值的时候,iOS还没有机会去更新此时的布局,此时iOS只是把当前的约束标记为的状态。

    添加如下代码,使约束添加动态效果:

        someViewHeightConstraint.constant = 200
        UIView.animate(withDuration: 1.0) {
            self.view.layoutIfNeeded()
        }
    
    2 检查和对约束做动画

    对于一些不能通过类似StoryBoard做可视化链接或者不想添加可视化的约束,可以通过代码创建。

    在一些情况如果想在runtime改变一个视图的约束的值,而有没有该约束的引用,可以通过遍历视图的constraints属性

        someView.constraints
    

    比如,如果想对一个在 container view 内水平居中的 titleLabel 动态修改约束值。可以做如下尝试:

            titleLabel.superview?.constraints.forEach { constraint in
                if constraint.firstItem === titleLabel && constraint.firstAttribute == .centerX {
                    constraint.constant =  -100.0 
                    return
                }
            }
    

    上面的代码实现的是水平居中约束左移100。

    当然也可以在创建约束的时候,对该约束的属性Identifier设置一个字符串标示。比如对如上的titleLabel水平居中约束添加标示为 titleCenterX。那么上面的代码可以替换为:

            titleLabel.superview?.constraints.forEach { constraint in
                if constraint.identifier == "titleCenterX" {
                    constraint.constant = -100
                    return
                }
            }
    
    3 替换已有约束做动画

    目前上面内容都是结束的对已经的约束改变属性constant的值做动画
    如果要实现一些更加复杂的动画效果呢,这时可能创建一个新的约束,然后替换已经存在的约束可能会实现起来更加的容易。

    在开始前需要知道的是,对于某个view已经存在的一个约束比如constraintA
    如果做如下处理:

    constraintA.isActive = false
    

    这会使当前视图层级把constraintA移除,如果此时外面又没有对constraintA的引用,那么constraintA将会被内存删除。

    对于一个在视图内居中的view来说,它的表现形式为:
    someView.centerX = multiple * superView.centerX + constant

    multiple 是倍数,一般等于1
    constant 移动距离,一般等于0

    在之前介绍的水平居中的titleLabel左移100的则可如下表示:
    titleLabel.centerX = 1.0*superView.centerX + -100.0

    如果titleLabel需要一个0.5倍水平居中的约束替换已有的水平居中约束,则可创建如下新约束:

            let newConstraint = NSLayoutConstraint(item: titleLabel,
                                                   attribute: .centerX,
                                                   relatedBy: .equal,
                                                   toItem: titleLabel.superview!,
                                                   attribute: .centerX,
                                                   multiplier: 0.5,
                                                   constant: 0)
            newConstraint.identifier = "titleCenterX"
            newConstraint.isActive = true
    

    newConstraint 的identifiers属性设置了一个字符串标示,这样是为了更好的调试。
    设置 newConstraint.isActive 告诉iOS在当前布局使用该约束。

    如果一次性创建了大量的约束,没必要对每一个约束动都设置一下
    someConstraint.isActive = true
    使用 NSLayoutConstraint.activate([NSLayoutConstraint]) 会更好的管理代码。

    4 整理

    1: 如果要对一个约束动态该constant属性值,记得在 UIView.animate(...)里调用
    self.view.layoutIfNeeded()告诉iOS需要重新布局了。

    2: 对于一个已经存在的约束,可以通过 IBOutlets ,代码引用, 或者简单粗暴的遍历查看 identifier 或者属性详情查找。

    3:对于一个约束,
    设置属性 isActive = false 会让该约束的view调用 view.removeConstraint(someConstraint);
    设置属性 isActive = true 会让该约束的view调用 view.addConstraint(someConstraint)。

    4:最后一个小知识

    一个需求,创建一个图片 imageView, imageView的初始约束为 屏幕水平居中,在屏幕外的正下方。想要对约束做动画移动到屏幕中间

    此时如果改变约束后调用 UIView.animate( self.view.layoutIfNeeded() ) 会看到imageView 直接从屏幕左上角(0, 0)处做动画到屏幕中间。
    因为虽然设置了初始约束位置,但是视图一直没有执行初始化布局,所以imageView的初始化布局位置会是默认左上角(0,0)

    修复问题: 在 UIView.animate( self.view.layoutIfNeeded() ) 之前再次调用一下 self.view.layoutIfNeeded() ,告诉iOS更新一下初始化布局。

            // set imageView initial layout
            self.view.layoutIfNeeded()
    
            // animating update imageView layout
            UIView.animate(withDuration: 1.0, animations: {
                self.view.layoutIfNeeded()
            })
    

    相关文章

      网友评论

          本文标题:Auto Layout Animation

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