Section I: View Animations

在该节主要介绍 UIKit 的一些动画API,动画作用于 UIView 或者 UIView 的子类。

Chapter 1: Getting Started

主要介绍 UIView.animate(...) 类方法通过改变视图的开始值结束值动画改变:
位置
大小
透明度
背景色

或者通过 CGAffineTransform 对视图进行:
旋转
伸缩
更改位置

Chapter 2: Springs

为了使视图的动画效果更接近于现实世界,UIKit 还提供了一个如下方法

        UIView.animate(withDuration: 1.0,
                       delay: 0.0,
                       usingSpringWithDamping: 0.4,
                       initialSpringVelocity: 10,
                       options: [],
                       animations: {
                        // change view properties
        }) { finished in
            // completion
        }

使视图在动画的时候添加一定的弹性效果。其中
dampingRation的区间是 [0,1],
0 代表弹性最大;1 代表几乎没弹性
velocity代表的是初速度

Chapter 3: Transitions

Transitions主要对视图进行动画添加与移除

添加一个新视图
    var animationContainerView: UIView!
    override func viewDidLoad() {
        //set up the animation container
        animationContainerView = UIView(frame: view.bounds)
        animationContainerView.frame = view.bounds
        view.addSubview(animationContainerView!)
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //create new view
        let newView = UIImageView(image: UIImage(named: "banner")!)
        newView.center = animationContainerView.center
        //add the new view via transition
        UIView.transition(with: animationContainerView,
                          duration: 0.33,
                          options: [.curveEaseOut, .transitionFlipFromBottom],
                          animations: {
                            self.animationContainerView.addSubview(newView)
        },
                          completion: nil
        )
    }

移除一个视图
//remove the view via transition
UIView.transition(with: animationContainerView, duration: 0.33,
  options: [.curveEaseOut, .transitionFlipFromBottom],
  animations: {
    self.newView.removeFromSuperview()
  },
  completion: nil
)
隐藏或者显示视图
//hide the view via transition
UIView.transition(with: self.newView, duration: 0.33,
  options: [.curveEaseOut, .transitionFlipFromBottom],
  animations: {
    self.newView.isHidden = true
  },
  completion: nil
)
视图A替换视图B
//replace via transition
UIView.transition(from: oldView, to: newView, duration: 0.33,
  options: .transitionFlipFromTop, completion: nil)

其实总结下来也就两个类方法:

UIView.transition from ViewA To ViewB
&
UIView.transition with ViewA 

然后通过设置动画的options会有一些3D的效果

Chapter 4: View Animations in

主要是

UIView.transition(...) 
UIView.animate(...)  
someView.transform(...)

3个方法的混合练习

Chapter 5: Keyframe animations

想象一个场景,需要把一个视图做如下动画:
A移动到B;
B移动到C;
C移动到D

如果不怕麻烦可以如下不断地在 completion里面嵌套实现:

        let sampleView = UIView()
        
        UIView.animate(withDuration: 0.5, animations: {
            sampleView.frame.origin = a
        }) { _  in

            UIView.animate(withDuration: 0.5, animations: {
            sampleView.frame.origin = b
            }) { _ in

                UIView.animate(withDuration: 0.5, animations: {
                    sampleView.frame.origin = c
                }) { _ in

                    UIView.animate(withDuration: 0.5, animations: {
                        sampleView.frame.origin = d
                    }) { _ in
                        
                    }
                }
            }
        }
    }

但是这样实在不易于维护也不好看,如果是更复杂的动画效果就更加不好处理了。在这种情况就可以使用keyframe animation了,把上面的移动动画先单独分离出来,再用keyframes合并就好了。
实现如下:

        let sampleView = UIView()
        
        UIView.animateKeyframes(withDuration: 2.0, delay: 0.0, options: [], animations: {
            UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25, animations: {
                sampleView.frame.origin = a
            })
            UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25, animations: {
                sampleView.frame.origin = b
            })
            UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25, animations: {
                sampleView.frame.origin = c
            })
            UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25, animations: {
                sampleView.frame.origin = d
            })
        }) { _ in
            // done
        }

值得注意的是参数 withRelativeStartTimerelativeDuration 都是相对值。比如整个运行时间是10秒的话,而相对开始时间 relativeStartTime = 0.5,那就是5秒开始了。

当然如果有一些其它的需求也可以在单独的 UIView.addKeyframe(...) 里面做一些背景色透明度的动画;或者 伸缩旋转等更复杂的transform动画

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

推荐阅读更多精彩内容