Edward Lim
Edward Lim

Reputation: 823

Custom Slide in animation when presenting navigation controller not working at all in swift

So I've been following a couple tutorials on how to perform a custom animation when presenting a view controller. I currently have the following,

  1. A class called TransitionManager which will be instantiated in ViewController A that will present the view
  2. ViewController A that will present ViewController B in a navigation controller

According to all the tutorials i've read after setting the delegate in the presentation of the view, I should see my custom transition. However, the default animation is still used instead. I've tried moving the setting of the delegate before and after presenting with no avail

Transition Manager Class

class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // get reference to our fromView, toView and the container view that we should perform the transition in
    let container = transitionContext.containerView
    let fromView = transitionContext.view(forKey: .from)!
    let toView = transitionContext.view(forKey: .to)!

    // set up from 2D transforms that we'll use in the animation
    let offScreenRight = CGAffineTransform(translationX: container.frame.width, y: 0)
    let offScreenLeft = CGAffineTransform(translationX: -container.frame.width, y: 0)

    // start the toView to the right of the screen
    if self.presenting {
        toView.transform = offScreenRight
    } else {
        toView.transform = offScreenLeft
    }


    // add the both views to our view controller
    container.addSubview(toView)
    container.addSubview(fromView)

    // get the duration of the animation
    // DON'T just type '0.5s' -- the reason why won't make sense until the next post
    // but for now it's important to just follow this approach
    let duration = self.transitionDuration(using: transitionContext)

    // perform the animation!
    // for this example, just slid both fromView and toView to the left at the same time
    // meaning fromView is pushed off the screen and toView slides into view
    // we also use the block animation usingSpringWithDamping for a little bounce
    UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: [], animations: {

        if self.presenting {
            toView.transform = offScreenLeft
        } else {
            toView.transform = offScreenRight
        }
        toView.transform = .identity

    }, completion: { finished in

        // tell our transitionContext object that we've finished animating
        transitionContext.completeTransition(true)

    })
    }

func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return 0.5
}

// MARK: UIViewControllerTransitioningDelegate protocol methods

// return the animataor when presenting a viewcontroller
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    self.presenting = true
    return self
}

// return the animator used when dismissing from a viewcontroller
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    self.presenting = false
    return self
}

}

Class ViewController A

class ViewControllerA: UIViewController {
let transitionManager = TransitionManager()
func addButtonSelected() {
        let vc = ViewControllerB()
        let nav = UINavigationController(rootViewController: vc)
        present(nav, animated: true, completion: nil)
        nav.transitioningDelegate = self.transitionManager

    }
}

Upvotes: 1

Views: 2666

Answers (2)

Tushar Sharma
Tushar Sharma

Reputation: 2882

Update your methods to swift3-:

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return Transition()
}

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return Transition()
}

Upvotes: 3

Brian Nickel
Brian Nickel

Reputation: 27550

You need to set the modalPresentationStyle to .custom, mentioned in the docs here and here. I'm not sure if it matters, but I've also always set the transitioning delegate before calling present:

nav.modalPresentationStyle = .custom
nav.transitioningDelegate = self.transitionManager
present(nav, animated: true, completion: nil)

Upvotes: 0

Related Questions