iOS转场动画一Push和Pop转场

字数 78阅读 352

一、Push和Pop转场

效果图.gif

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
            }
        }
    }
}

推荐阅读更多精彩内容