0

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.

Paul Cezanne
  • 8,629
  • 7
  • 59
  • 90

1 Answers1

0

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)

Community
  • 1
  • 1
gp-v
  • 114
  • 1
  • 7