一、Push和Pop转场
1、从第一个controller进入第二个controller的时候设置navigationController代理
let vc = SecondPageController()
self.navigationController?.delegate = vc
self.navigationController?.pushViewController(vc, animated: true)
2、第二个controller遵守UINavigationControllerDelegate协议,并实现代理方法
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return PageCoverTransition((operation == UINavigationControllerOperation.push) ? .push: .pop)
}
3、然后就是新建一个过渡动画的类(以PageCoverTransition为例),在改类中实现动画效果
import UIKit
enum PageCoverTransitionType:Int {
case push = 0
case pop
}
class PageCoverTransition: NSObject, UIViewControllerAnimatedTransitioning {
var type:PageCoverTransitionType?
init(_ myType:PageCoverTransitionType) {
super.init()
type = myType
}
//MARK:-UIViewControllerAnimatedTransitioning
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 1
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
switch type! {
case .push:
self.pushAnimation(transitionContext)
break
case .pop:
self.popAnimation(transitionContext)
break
}
}
/**
* 实现push动画
*/
func pushAnimation(_ transitionContext:UIViewControllerContextTransitioning){
let toVC = transitionContext.viewController(forKey: .to)!
let fromVC = transitionContext.viewController(forKey: .from)!
//对tempView做动画,避免bug;
let tempView:UIView = fromVC.view.snapshotView(afterScreenUpdates: false)!
tempView.frame = fromVC.view.frame
let containerView = transitionContext.containerView
containerView.addSubview(toVC.view)
containerView.addSubview(tempView)
fromVC.view.isHidden = true
containerView.insertSubview(toVC.view, at: 0)
//设置锚点
tempView.setAnchorPointTo(CGPoint(x: 0, y: 0.5))
//设置翻页效果
var transfrom3d = CATransform3DIdentity
transfrom3d.m34 = -0.002
containerView.layer.sublayerTransform = transfrom3d
//增加阴影(渐变色)
let fromGradient = CAGradientLayer()
fromGradient.frame = fromVC.view.bounds
fromGradient.colors = [UIColor.black.cgColor, UIColor.black.cgColor]
fromGradient.startPoint = CGPoint(x:0,y:0.5)
fromGradient.endPoint = CGPoint(x: 0.8, y: 0.5)
let fromShadow = UIView(frame: fromVC.view.bounds)
fromShadow.backgroundColor = UIColor.clear
fromShadow.layer.insertSublayer(fromGradient, at: 1)
fromShadow.alpha = 0
tempView.addSubview(fromShadow)
//
let toGradient = CAGradientLayer()
toGradient.frame = fromVC.view.bounds
toGradient.colors = [UIColor.black.cgColor, UIColor.black.cgColor]
toGradient.startPoint = CGPoint(x:0,y:0.5)
toGradient.endPoint = CGPoint(x: 0.8, y: 0.5)
let toShadow = UIView(frame: fromVC.view.bounds)
toShadow.backgroundColor = UIColor.clear
toShadow.layer.insertSublayer(fromGradient, at: 1)
toShadow.alpha = 1
toVC.view.addSubview(toShadow)
//动画
UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
tempView.layer.transform = CATransform3DMakeRotation(CGFloat(-M_PI_2), 0, 1, 0)
fromShadow.alpha = 1.0
toShadow.alpha = 0.0
}) { (finished) in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
if transitionContext.transitionWasCancelled{ //没有完成翻页
tempView.removeFromSuperview()
fromVC.view.isHidden = false
}
}
}
/**
* 实现pop动画
*/
func popAnimation(_ transitionContext:UIViewControllerContextTransitioning){
let toVC = transitionContext.viewController(forKey: .to)!
let fromVC = transitionContext.viewController(forKey: .from)!
let containerView = transitionContext.containerView
//拿到push时候的
let tempView = containerView.subviews.last
containerView.addSubview(toVC.view)
UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
tempView?.layer.transform = CATransform3DIdentity
fromVC.view.subviews.last?.alpha = 1.0
tempView?.subviews.last?.alpha = 0
}) { (finished) in
if transitionContext.transitionWasCancelled{
transitionContext.completeTransition(false)
}else{
transitionContext.completeTransition(true)
tempView?.removeFromSuperview()
toVC.view.isHidden = false
}
}
}
}