2

While animation of one segue(like perforrmsegue) is going, if other segue occures (if user press other button at that time) then application is crashing.

The same problem for the pop and pushViewController on UINavigationController is solved here.

Can we use same trik for segue also or there is other solution.

I get the following stack after crash. (Exeption at [NSException initWithCoder:]).

0   CoreFoundation  0x2f9fbf4b  __exceptionPreprocess
1   libobjc.A.dylib 0x39d8b6af  objc_exception_throw
2   CoreFoundation  0x2f9fbe8d  -[NSException initWithCoder:]
3   UIKit   0x3217a48f  -[UIView(Internal) _addSubview:positioned:relativeTo:]
4   UIKit   0x3217a417  -[UIView(Hierarchy) addSubview:]
5   UIKit   0x32342b71  __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke
6   UIKit   0x321806e5  +[UIView(Animation) performWithoutAnimation:]

If this exeption is for any other reason then please mention that because I an not sure about the segue.

Community
  • 1
  • 1
Pushparaj
  • 415
  • 8
  • 21
  • I am using `performSegueWithIdentifier` at many places in my controller on the button event. By the way application is working fine but crasing only sometimes if I press two buttons at the same time. – Pushparaj Mar 15 '14 at 09:57
  • I think simillar problem is explained here - http://stackoverflow.com/questions/19560198/ios-app-error-cant-add-self-as-subview. so many people should also face this problem with segue. – Pushparaj Mar 15 '14 at 09:59
  • What did you end up doing? Have you introduced a BOOL or is there some flag that iOS provides? – Stefan Arn Apr 03 '14 at 05:22
  • For anyone looking for a solution. This one worked flawlessly for me: http://stackoverflow.com/questions/20083276/cant-add-self-as-subview#comment32046015_21031034 – Stefan Arn Apr 03 '14 at 05:38
  • I have added shouldPerformSegueWithIdentifier:sender: and in that method check the value of `((RS_AppDelegate *)[UIApplication sharedApplication].delegate).animatingViewControllerTransition` and return NO if it's animating otherwise return YES. – Pushparaj Apr 08 '14 at 05:03

2 Answers2

2

This solution worked for me and I think it's general practice to add this in the program.

1)

First add BOOL property to your .h file of your app's appDelegate

@property (nonatomic) BOOL animatingViewControllerTransition;

Also implement the UINavigationControllerDelegate:

@interface Your_AppDelegate : UIResponder <UIApplicationDelegate, UINavigationControllerDelegate>

Set Your_AppDelegate as UINavigationController's delegate in application:didFinishLaunchingWithOptions: of your appDelegate:

((UINavigationController *)self.window.rootViewController).delegate = self;

2)

Now Add this UINavigationControllerDelegate method in .m file of your appDelegate:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{

    // Push/pop operation is allowed now.
    ((Your_AppDelegate *)[UIApplication sharedApplication].delegate).animatingViewControllerTransition = NO;
}

3)

Finally Add the following code whenever you are segueing

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    // Don't allow to segue if already one of the view controllers is being animated
    BOOL viewControllerIsTransitioning = ((Your_AppDelegate *)[UIApplication sharedApplication].delegate).animatingViewControllerTransition;
    if (viewControllerIsTransitioning)
    {
        return NO;
    }

    return YES;
}

Hope this will help to one having segue crash problem.

Pushparaj
  • 415
  • 8
  • 21
  • animatingViewControllerTransition doesn't exist – Pablo Martinez Nov 19 '14 at 18:54
  • `animatingViewControllerTransition` is a BOOL property in your appDelegate that you have to add. – Pushparaj Nov 20 '14 at 07:27
  • 1) In many cases rootViewController is not an instance of UINavigationController, so - for example when UITabBarController is used, we have to set delegate for all Navigation Controllers in rootViewController.viewControllers 2) You also have to set the flag to YES in willShowViewController. – Tomasz Slanina Oct 12 '16 at 09:12
1

I think this is a more simpler solution:

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    return self == [self.navigationController.viewControllers lastObject] ? YES : NO;
}
flyerz
  • 2,015
  • 1
  • 13
  • 7
  • Yes, it's quite simpler and there are many way to resolve this, but I have prefered one I stated in my answer because I am also using tabControler and other library related to navigationController like MMDrawerController so it handles all the cases. – Pushparaj May 15 '15 at 06:26
  • When you want to replace a method in all subclasses, you can use the method swizzling: http://nshipster.com/method-swizzling/ – flyerz May 16 '15 at 08:32