Skip to content

Instantly share code, notes, and snippets.

@alanzeino
Created January 8, 2017 00:12
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alanzeino/603293f9da5cd0b7f6b60dc20bc766be to your computer and use it in GitHub Desktop.
Save alanzeino/603293f9da5cd0b7f6b60dc20bc766be to your computer and use it in GitHub Desktop.
Replacing a UINavigationController's default animation transition with a custom transition
//
// NavigationController.swift
//
import UIKit
class NavigationController: UINavigationController {
init() {
super.init(nibName: nil, bundle: nil)
delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension NavigationController: UINavigationControllerDelegate {
public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return NavigationControllerAnimation(operation: operation)
}
}
class NavigationControllerAnimation: NSObject, UIViewControllerAnimatedTransitioning {
let operation: UINavigationControllerOperation
init(operation: UINavigationControllerOperation) {
self.operation = operation
super.init()
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else { return }
let containerView = transitionContext.containerView
if operation == .push {
toViewController.view.frame = containerView.bounds.offsetBy(dx: containerView.frame.size.width, dy: 0.0)
containerView.addSubview(toViewController.view)
UIView.animate(withDuration: transitionDuration(using: transitionContext),
delay: 0,
options: [ UIViewAnimationOptions.curveEaseOut ],
animations: {
toViewController.view.frame = containerView.bounds
fromViewController.view.frame = containerView.bounds.offsetBy(dx: -containerView.frame.size.width, dy: 0)
},
completion: { (finished) in
transitionContext.completeTransition(true)
})
} else if operation == .pop {
containerView.addSubview(toViewController.view)
UIView.animate(withDuration: transitionDuration(using: transitionContext),
delay: 0,
options: [ UIViewAnimationOptions.curveEaseOut ],
animations: {
fromViewController.view.frame = containerView.bounds.offsetBy(dx: containerView.frame.width, dy: 0)
toViewController.view.frame = containerView.bounds
},
completion: { (finished) in
transitionContext.completeTransition(true)
})
}
}
}
@superarts
Copy link

If it's based on Storyboard, shouldn't it be something like below?

class ABNavigationController: ABNavigationControllerBase, UINavigationControllerDelegate {
    required init?(coder aDecoder: NSCoder) {
		super.init(coder: aDecoder)
        delegate = self
    }
}

@alanzeino
Copy link
Author

I have no idea, I don't use Storyboards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment