I'm presenting a modal view controller using a custom transition (by setting its modelPresentationStyle
to UIModalPresentationCustom
, providing a transitioning delegate, and UIViewControllerAnimatedTransitioning
object).
In the presented view controller, I have an unwind segue hooked up to a button. The segue fires just fine; the IBAction
method in the presenting view controller is called, and so is prepareForSegue
in the presented view controller. However, the presented view controller is not dismissed, and the appropriate transitioning delegate method (animationControllerForDismissedController:
) is not called.
If, however, I set the presented view controller's modalPresentationStyle
to UIModalPresentationFullScreen
(the default), the view controller is dismissed properly (this breaks my custom transition, though).
I'm at a complete loss at what to do here. I've looked through Apple's documentation, and didn't notice anything saying that one had to do special things with unwind segues when dealing with custom transitions.
I'm aware that I could call dismissViewControllerAnimated:completion:
in the IBAction
method of the presenting view controller, but I'd rather use that as a last resort, and get the unwind segue working the way it should (or at least know why it's not working :) ).
Any help would be much appreciated,
Thanks in advance
It seems that if you use UIModalPresentationCustom
to present the controller with a custom transition manager, you also need to use a custom transition manager to dismiss it (which makes sense I guess, since you can do all kinds of weird stuff in the animator object and UIKit can't be sure that just dismissing the screen as usual will completely restore the original state - I just wish it told you that explicitly...).
Here's what I've done to fix this in my app:
segueForUnwindingToViewController
in the parent view controller (the one to which you're moving after the dismiss animation) and return an instance of your UIStoryboardSegue
, either the one you've used for the original transition or a new separate classperform
method call dismissViewControllerAnimated
dismissViewControllerAnimated
(it's possible that changing modelPresentationStyle
to e.g. full screen before dismissing would work too, but I haven't tried that)animationControllerForDismissedController
in the transition manager object and return a proper animatortarget.navigationController!.popToViewController(target, animated: false)
)Complete code sample:
// custom navigation controller
override func segueForUnwindingToViewController(toViewController: UIViewController,
fromViewController: UIViewController,
identifier: String?) -> UIStoryboardSegue {
return CustomSegue(
identifier: identifier,
source: fromViewController,
destination: toViewController
)
}
// presented VC
var customTransitionManager: UIViewControllerTransitioningDelegate?
// custom segue
override func perform() {
let source = sourceViewController as! UIViewController
if let target = destinationViewController as? PresentedViewController {
let transitionManager = TransitionManager()
target.modalPresentationStyle = .Custom
target.customTransitionManager = transitionManager
target.transitioningDelegate = transitionManager
source.presentViewController(target, animated: true, completion: nil)
} else if let target = destinationViewController as? WelcomeViewController {
target.navigationController!.popToViewController(target, animated: false)
target.dismissViewControllerAnimated(true, completion: nil)
} else {
NSLog("Error: segue executed with unexpected view controllers")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With