Main View Controller action that displays the First Modal
@IBAction func button(sender: AnyObject) {
let sb = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
if let vc = sb.instantiateViewControllerWithIdentifier("VC1") as? FirstViewController {
vc.modalPresentationStyle = .OverCurrentContext
vc.modalTransitionStyle = .CrossDissolve
presentViewController(vc, animated: true, completion: nil)
}
}
VC1 That has a custom animation to transition to the 2nd view controller
@IBAction func go(sender: AnyObject) {
guard let vc = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("VC2") as? SecondViewController else {return}
vc.transitioningDelegate = transitionManager
vc.modalPresentationStyle = .CurrentContext
presentViewController(vc, animated: true, completion: nil)
}
VC2 - just a dismiss call
@IBAction func dismiss(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
VC2 is the one that doesn't work. Currently, it dismisses itself to VC1. I'd like it to go back to Main without going back first.
Transition Manager
class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
// TRANSITION PROTOCOL METHODS
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
guard let container = transitionContext.containerView() else {return}
guard let toView = transitionContext.viewForKey(UITransitionContextToViewKey) else {return}
guard let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) else {return}
// set up from 2D transforms that we'll use in the animation
let width = container.frame.width
let offScreenRight = CGAffineTransformMakeTranslation(width, 0)
let offScreenLeft = CGAffineTransformMakeTranslation(-width, 0)
toView.transform = offScreenRight
container.addSubview(toView)
container.addSubview(fromView)
let duration = self.transitionDuration(transitionContext)
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: .AllowAnimatedContent, animations: {
fromView.transform = offScreenLeft
toView.transform = CGAffineTransformIdentity
}) { finished in
transitionContext.completeTransition(true)
}
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 1.4
}
// DELEGATE METHODS
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
}
I've tried putting it into a nav controller, dismissing through self.presentingViewController.dismissViewcontroller, and a bunch of other things. I feel I'm missing something very fundamental about View Controllers that will bust this wide open.
Gif of how it shouldn't work:
I'd like 2 to go back to Home without seeing 1 again
EDIT: I've got this to work:
presentingViewController?.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
But it doesn't feel right and doesn't look right. The main reason I'm doing this style is because the modals in the actual project have translucent backgrounds, so a normal nav controller or regular transition causes them to overlap in ugly ways.
It's also a one way street kind of thing. VC1 should not be seen after VC2 is presented so maybe I'm just thinking about this entirely wrong and a different style component is the best.