I've created some unwind segues in XCode and by default they come with an animation which I don't want. After some searching around in Stack Overflow I did find that there is supposed to be a check box you can untick to disable animation, but that comes in Xcode 7 which I cannot upgrade to. How would I disable the unwind segue animation programmatically? I'm currently running XCode 6.4.
Let's name controller you are unwinding to FirstController
and the one you are dismissing SecondController
. Also there are two cases here: one when SecondController
presented modally and one with UINavigationController
involved.
Unwind segue resets/ignores modalPresentationStyle
, have to tweak it. In IBAction
method called on FirstController
upon unwinding add the following (I will assume you called this method prepareForUnwind
):
- (IBAction)prepareForUnwind:(UIStoryboardSegue *)segue {
//TODO: add right condition if you have to
UIViewController* secondController = (UIViewController*)segue.sourceViewController;
secondController.transitioningDelegate = self;
secondController.modalPresentationStyle = UIModalPresentationCustom;
}
This part will work when SecondController
is dismissed from being modal. Now, for case when both controllers reside on UINavigationController
, FirstController
should become its delegate:
- (void)viewDidLoad {
self.navigationController.delegate = self;
}
This will make UIKit to ask FirstController
for animator object for ensuing transitions. Now we should modify FirstController
to return it.
In FirstController.h
:
@interface FirstController : UIViewController<UIViewControllerTransitioningDelegate, UINavigationControllerDelegate>
Add corresponding code to FirstController.m
, so it would return some animator object for both cases (mind comments):
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
return [Animator new];
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC {
//This will disable ALL animations on particular UINavigationController
//return nil to use default animation when appropriate
return [Animator new];
}
Now implement Animator
itself. It should confirm UIViewControllerAnimatedTransitioning
protocol.
In Animator.h
:
@interface Animator : NSObject<UIViewControllerAnimatedTransitioning>
@end
In Animator.m
:
@implementation Animator
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
return 0;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController *controllerToDismiss = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIView *viewToDismiss = [transitionContext viewForKey:UITransitionContextFromViewKey];
CGRect frameToDismissTo = [transitionContext finalFrameForViewController:controllerToDismiss];
viewToDismiss.frame = frameToDismissTo;
UIViewController *controllerToPresent = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *viewToPresent = [transitionContext viewForKey:UITransitionContextToViewKey];
CGRect frameToPresentTo = [transitionContext finalFrameForViewController:controllerToPresent];
viewToPresent.frame = frameToPresentTo;
[[transitionContext containerView] addSubview:viewToPresent];
[transitionContext completeTransition:YES];
}
@end
Answer based on this post and this so answer (both not mine)