Search code examples
iosswiftuiviewcontrollertransition

How to change the default transition while presenting UIViewController to custom


i am trying to present another UIViewController from my current view controller. The transition animation is set to default and the presented UIViewController seems to be appearing from bottom to top . however i am trying to set the animation from top to Bottom. How can i acheive this? I have tried using transition effects as cover vertical, flip horizontal, cross dissolve but none of them seems according to my choice. Any suggestions how can I achieve this?

 let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let editCategoryVC: EditCategoryVC = storyboard.instantiateViewControllerWithIdentifier("editCategoryVC")as EditCategoryVC
        self.presentViewController(editCategoryVC, animated:true, completion: nil

)


Solution

  • TransitionHandler helper class that handles animation

    import UIKit
    
    class TransitionHandler : NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate  {
    
        func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return self
        }
    
        func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return self
        }
    
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
    
            return 0.9
        }
    
        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    
            let container = transitionContext.containerView
            let fromView = transitionContext.view(forKey: .from)!
            let toView = transitionContext.view(forKey: .to)!
    
            // e.g to show the animation from x axis change this frame as required
            //   let offScreenUp = CGAffineTransformMakeTranslation(-container.frame.size.width, 0)
            //     let offScreenDown = CGAffineTransformMakeTranslation(container.frame.size.width,0)
            let offScreenUp = CGAffineTransform(translationX: 0, y: 0) // (-container.frame.size.width,0)
            let offScreenDown = CGAffineTransform(translationX: 0, y: container.frame.size.height)
            toView.transform = offScreenUp
            container.addSubview(toView)
            container.addSubview(fromView)
            let duration = self.transitionDuration(using: transitionContext)
    
            UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.8, options: [], animations: {
    
                fromView.transform = offScreenDown
                toView.transform = CGAffineTransform.identity
    
        }, completion: { finished in
    
                transitionContext.completeTransition(true)
        })
    
        }
    }
    

    Your class that shows next controller on button click

    class ViewController: UIViewController {
    
        let transitionHandler = TransitionHandler()
    
        @IBAction func showVCAnimation(sender: AnyObject) {
    
            var storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let nextVC = storyboard.instantiateViewControllerWithIdentifier("editCategoryVC") as EditCategoryVC
            nextVC.transitioningDelegate =  self.transitionHandler
            self.presentViewController(nextVC, animated: true, completion: nil)
        }
    }
    

    Well Thanks to AppCoda!!!