0

I have a pan gesture that I have added on my app's root view controller on the 1st level to let the user swipe anywhere to go to the previous level in the navigation stack (the gesture is not on the 0 level to prevent going into a black hole :) ). This has worked and still works perfectly fine on iOS versions prior to 7.

When I try to swipe back using iOS 7, I get these messages in the console: [11050:a0b] nested pop animation can result in corrupted navigation bar [11050:a0b] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

At this point, the app hasn't crashed.

Then when I try to swipe back one more time to the previous level, it crashes. I'm just trying to figure out why this bug has risen in iOS 7, and how I can fix it. Any help is duly and greatly appreciated!

Here is my code:

RootViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pop:)];

    pan.delegate = self;

    [self.view addGestureRecognizer:pan];
}

- (void)pop:(UIPanGestureRecognizer*)pan
{
    if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)
    {
        CGPoint vel = [pan velocityInView:self.view];

        if (vel.x > 1000)
        {
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
}
klcjr89
  • 5,862
  • 10
  • 58
  • 91

3 Answers3

1

I suspect the problem is your state condition. By testing for UIGestureRecognizerStateBegan and UIGestureRecognizerStateChanged, the delegate is triggering many pops (which are animated, so the next pop is triggered while the previous one is still animating).

Instead, test if (pan.state == UIGestureRecognizerStateEnded) to get just the one you need.

Also, don't worry about popping into nowhere when the NavVC is already at root. It's smart enough not to pop the root.

(As to why this is misbehaving in os7 only, I can only speculate that < ios7 logic removes the gesture recognizers at an earlier stage in the pop process).

danh
  • 62,181
  • 10
  • 95
  • 136
  • Perfect answer. This was the solution, and the detailed response was helpful. – klcjr89 Sep 19 '13 at 20:45
  • Glad it was useful. I was thinking if you want the pop to start as soon as the gesture is recognized, you could test for that, but then set pan.delegate = nil, or remove it from the view so you get no further messages. Not sure if that will look better in your UI. (It's easy to try). – danh Sep 19 '13 at 20:49
  • Hmm, I have the same gesture used on a WebView that displays a pdf, and the same crash appears as mentioned earlier, despite changing the gesture state, any thoughts on this? – klcjr89 Sep 19 '13 at 21:08
  • Is the UIWebView's built in pan recognizer interfering with mine? – klcjr89 Sep 19 '13 at 21:27
  • Yikes. Not sure. Check out this SO answer about making your GR play nice with the web views. Hopefully that fixes it. http://stackoverflow.com/questions/7487182/mpmovieplayercontroller-view-not-recognize-touch – danh Sep 19 '13 at 21:32
  • Thank you for the link provided. Turns out that didn't help me either. – klcjr89 Sep 19 '13 at 22:16
1

If there is a back button visible for the current controller in the UINavigationController's stack, the user will be able to swipe right from the left edge of the screen to go back. You may want to consider not adding the pan gesture recognizer if the app is running on iOS7.

You can check the iOS version using [UIDevice currentDevice].systemVersion.

I realize your question stated that you added the gesture recognizer to allow the user to swipe anywhere to go back, but (hopefully) iOS7 users will quickly become familiar with the swipe from the left edge of the screen.

Greg
  • 33,450
  • 15
  • 93
  • 100
  • Thank you for your comment, but I'm not using the stock chevron arrow style back button that iOS provides. It's not that great and doesn't work well with cases. – klcjr89 Sep 19 '13 at 20:50
0

The thing happening when the velocity reaches 1000 its gonna pop the viewcontroller everytime the function is called and when its animated is YES it will get called several times before it pops the viewcontroller which I think gives you the crash.

Arbitur
  • 38,684
  • 22
  • 91
  • 128
  • So why is iOS 7 not liking it, but other versions don't mind? And lastly, any ideas on how I can fix this sir? Thank you! – klcjr89 Sep 19 '13 at 20:36