美文网首页
iOS转场动画一Push和Pop转场

iOS转场动画一Push和Pop转场

作者: MillerWang | 来源:发表于2017-02-24 16:52 被阅读267次

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

    相关文章

      网友评论

          本文标题:iOS转场动画一Push和Pop转场

          本文链接:https://www.haomeiwen.com/subject/wepwwttx.html