iOS 给 storyboard 创建的 view 添加动画效果

使用 storyboard, xib 创建的视图, 视图的约束是用的 Autolayout , 所以实现动画效果也要通过改变约束的值,而不是直接改变 frame

示例: 在控制器上添加一个 blueView, blueView 上添加一个 greenView, 现改变 blueView 的宽度实现动画效果

一. 改变约束值实现动画

将 blueView 的宽度拉成属性 BlueView_Width, 改变 BlueView_Width 的 constant 值, 然后在UIView.animate 中添加                 strongSelf.view.layoutIfNeeded(), 更新controller View 的子视图布局, 不添加的 strongSelf.view.layoutIfNeeded() 没有动画效果

blueView 是 View 的子视图, blueView 的宽度改变时, view 的 viewWillLayoutSubviews 会执行

        @IBOutlet weak var blueView: UIView!
        @IBOutlet weak var greenView: UIView!
        @IBOutlet weak var BlueView_Width: NSLayoutConstraint!

        let blueWidth = BlueView_Width.constant + 10
        BlueView_Width.constant = blueWidth
        UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in
            if let strongSelf = self {
                strongSelf.view.layoutIfNeeded()
            }
            
        }, completion: nil)

二.使用 frame 实现动画

 view 的 viewWillLayoutSubviews  不会执行

错误:

blueView 的宽度改变了, 但是 greenView 的宽度没有随着改变

UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in
            if let strongSelf = self {
                let blueWidth = strongSelf.blueView.frame.width + 10
                strongSelf.blueView.frame.size.width = blueWidth
                strongSelf.view.layoutIfNeeded()

            }
        }, completion: nil)

因为 blueView 和 greenView  的约束是通过 Autolayout 创建的, 所以改变 blueView frame 时, 它的子视图并不会随之改变, view 的 viewWillLayoutSubviews 不会执行, 要让 greenView 宽度改变, 需要改变 greenView 的 frame

UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in
            if let strongSelf = self {
                let blueWidth = strongSelf.blueView.frame.width + 10
                strongSelf.blueView.frame.size.width = blueWidth
                strongSelf.greenView.frame.size.width = 70
                strongSelf.view.layoutIfNeeded()
            }
            
        }, completion: nil)

如果使用 blueView 的 layoutIfNeeded() 方法, 需要写在改变 greenView 宽度之前, 写在之后没有效果

UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: { [weak self] in
            if let strongSelf = self {
                let blueWidth = strongSelf.blueView.frame.width + 10
                strongSelf.blueView.frame.size.width = blueWidth
                strongSelf.blueView.layoutSubviews()
                strongSelf.greenView.frame.size.width = 70
            }
            
        }, completion: nil)

猜你喜欢

转载自blog.csdn.net/LeeCSDN77/article/details/82349197