Controller的转场动画主要是通过UIViewControllerAnimatedTransitioning 和 UIViewControllerTransitioningDelegate 来完成。
实现效果:
首先,创建一个class PresentViewControllerAnimation,继承自NSObject,遵守UIViewControllerAnimatedTransitioning。然后创建一个初始化方法,声明一个originFrame来保存初始化的frame。这里遵守UIViewControllerAnimatedTransitioning之后需要实现两个方法,一个是transitionDuration,一个是animateTransition。transitionDuration是代表动画时长,那么animateTransition里面就是动画的实现。这里
- login button 沿y轴顺时针旋转90度。
- 以login button 的大小在该位置snapshot,但初始位置在y轴上逆时针90度,这样让 login button 旋转看起来连续。
- 然后沿着y轴顺时针旋转90度。
- 放大snapshot填满屏幕。
动画完了之后,将toview 显示出来,将snapshot移除,将 login button 位置还原。记得还需要调用transitionContext.completeTransition方法,否则页面会卡着不动。
class PresentViewControllerAnimation: NSObject,UIViewControllerAnimatedTransitioning {
private let originFrame: CGRect
init(originFrame: CGRect) {
self.originFrame = originFrame
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 2.0
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromVC = transitionContext.viewController(forKey: .from) as? LoginViewController,
let toVC = transitionContext.viewController(forKey: .to) as? GiftViewController,
let snapshot = toVC.view.snapshotView(afterScreenUpdates: true)
else {
return
}
let containerView = transitionContext.containerView
let finalFrame = transitionContext.finalFrame(for: toVC)
snapshot.frame = originFrame
snapshot.layer.cornerRadius = originFrame.width / 2