iOS swift转场动画by TransitioningDel

作者: Mcccc | 来源:发表于2016-11-18 13:53 被阅读491次

    转场动画

    以我们常用的present、push转场动画为例,这种过渡性视图展示效果被抽象成UIViewControllerAnimatedTransitioning协议

    如下图,A present 到B则是调用系统默认的present协议,自定义转场动画则是实现UIViewControllerAnimatedTransitioning,重写协议中的动画对象animator

    present的原理.png

    tip:当B.transitioningDelegate=nil时,B就会调用系统默认的present协议

    自定义转场动画

    咋们先看看要实现效果,图标有点丑,勿见怪hah


    转场动画menu.gif
    • 实现转场动画delegate

    主要思路:
    1、使用系统默认present转场操作
    2、重写转场协议,设置动画时间、动画过渡效果
    3、设置present to 对象的转场协议为 [步骤2 ]的协议
    4、run~

    协议实现的工具类如下

    import UIKit
    
    class MenuTransitionHepler: NSObject,UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate {
        
        private var isPresenting = false
        
        //实现UIViewControllerAnimatedTransitioning代理方法
        
        //过场动画持续时间
        func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
            return 0.5
        }
        
        //过场动画实现
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
            
            let container = transitionContext.containerView
    
            let toVC=transitionContext.viewController(forKey: !self.isPresenting ? UITransitionContextViewControllerKey.from : UITransitionContextViewControllerKey.to)!
            
    //        let fromVC=transitionContext.viewController(forKey: !self.isPresenting ? UITransitionContextViewControllerKey.to : UITransitionContextViewControllerKey.from)!
            
    //        let fromView    = fromVC.view
            let toView      = toVC.view
            
            //设置动画初始位置
            if self.isPresenting {
                self.setOffAnimation(menuVC: toVC as! MenuVC)
            }
            
            container.addSubview(toView!)
            
            let duration = self.transitionDuration(using: transitionContext)
    
            UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: UIViewAnimationOptions.curveLinear, animations: {
                
                if self.isPresenting{
                    self.setOnAnimation(menuVC: toVC as! MenuVC)
    
                }else{
                    self.setOffAnimation(menuVC: toVC as! MenuVC)
                }
                
            }, completion: {(finish:Bool) in
                
                transitionContext.completeTransition(true)
                
            })
            
    
            
            
    
        }
        
        func offCGAffineTransform(amount:CGFloat) -> CGAffineTransform {
            return CGAffineTransform(translationX: amount, y: 0)
        }
        
        func setOffAnimation(menuVC:MenuVC){
            menuVC.view.alpha = 0
            
            // setup paramaters for 2D transitions for animations
            let topRowOffset  :CGFloat = 300
            let middleRowOffset :CGFloat = 150
            let bottomRowOffset  :CGFloat = 50
            
            menuVC.img_businessCar.transform = self.offCGAffineTransform(amount: -topRowOffset)
            menuVC.l_businessCar.transform = self.offCGAffineTransform(amount: -topRowOffset)
            
            menuVC.img_taxi.transform = self.offCGAffineTransform(amount: topRowOffset)
            menuVC.l_taxi.transform = self.offCGAffineTransform(amount: topRowOffset)
            
            menuVC.img_bus.transform = self.offCGAffineTransform(amount: -middleRowOffset)
            menuVC.l_bus.transform = self.offCGAffineTransform(amount: -middleRowOffset)
            
            menuVC.img_selfDrive.transform = self.offCGAffineTransform(amount: middleRowOffset)
            menuVC.l_selfDrive.transform = self.offCGAffineTransform(amount: middleRowOffset)
            
            menuVC.img_gasStation.transform = self.offCGAffineTransform(amount: -bottomRowOffset)
            menuVC.l_gasStation.transform = self.offCGAffineTransform(amount: -bottomRowOffset)
            
            menuVC.img_service.transform = self.offCGAffineTransform(amount: bottomRowOffset)
            menuVC.l_service.transform = self.offCGAffineTransform(amount: bottomRowOffset)
        }
        
        func setOnAnimation(menuVC:MenuVC){
            menuVC.view.alpha = 1
            
            menuVC.img_businessCar.transform = CGAffineTransform.identity
            menuVC.l_businessCar.transform = CGAffineTransform.identity
            
            menuVC.img_taxi.transform = CGAffineTransform.identity
            menuVC.l_taxi.transform = CGAffineTransform.identity
            
            menuVC.img_bus.transform = CGAffineTransform.identity
            menuVC.l_bus.transform = CGAffineTransform.identity
            
            menuVC.img_selfDrive.transform = CGAffineTransform.identity
            menuVC.l_selfDrive.transform = CGAffineTransform.identity
            
            menuVC.img_gasStation.transform = CGAffineTransform.identity
            menuVC.l_gasStation.transform = CGAffineTransform.identity
            
            menuVC.img_service.transform = CGAffineTransform.identity
            menuVC.l_service.transform = CGAffineTransform.identity
        }
        
        
        //UIViewControllerTransitioningDelegate代理方法
        //presented
        func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            self.isPresenting=true
            return self
        }
        
        //dismissed
        func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            self.isPresenting=false
            return self
        }
        
        
        
    }
    

    to VC里面设置present代理

     let transitionHelper = MenuTransitionHepler()
    
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
            self.transitioningDelegate=self.transitionHelper
        }
        
    

    思考

    1、后续可延伸交互式转场动画
    2、交互式过场动画是否可作侧滑框架?

    demo传送门,如果觉得有帮助还望给个star以示支持,thx~
    https://github.com/marceChow/-

    相关文章

      网友评论

      • 412f468e2ba9:谢谢楼主哈。
        options: UIViewAnimationOptions.curveLinear
        这是设置点击的动画吗,修改curveLinear为其他值却没有变化。
        还有返回按钮的动画是在哪里设置的。

      本文标题:iOS swift转场动画by TransitioningDel

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