1

In my app, I have UIViewControllers A,B,C,D. What I do it traverse from A to B to C to D. Now the stack reads like A,B,C,D

I then remove C and D which are the top 2 items in the stack using

[self.navigationController popToViewController:BViewController animated:NO];

When I NSLog now I have A,B in the stack. Now when I try moving to C I get "nested push animation can result in corrupted navigation bar". I am puzzled why this is happening. Can anyone please help me in resolving this issue. Thanks for your time

EDIT From B I go to C using the below code

UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *viewController = [storybord instantiateViewControllerWithIdentifier:@"C"];
[self.navigationController pushViewController:viewController animated:YES];

After this code is executed, there is an asynchronous code where we push to D

UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *viewController = [storybord instantiateViewControllerWithIdentifier:@"D"];
[self.navigationController pushViewController:viewController animated:YES];

The stack now reads A,B,C,D. When I pop, the issue occurs

ASYNCHRONOUS CODE

 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

            if (error) {
                NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
                [defaults setValue:@"messagehomescreen" forKey:@"lastscreenstatus"];
                UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
                UIViewController *viewController = [storybord instantiateViewControllerWithIdentifier:@"D"];
                [self.navigationController pushViewController:viewController animated:YES];

            } 
        }];
Timothy Rajan
  • 1,947
  • 8
  • 38
  • 62
  • You are using the right thing to pop back to the B controller (as far as I can tell). Can you show your code for where you are pushing from B to C please. – Fogmeister Jan 13 '14 at 10:00
  • Hmm... what do you mean asynchronous? Please show all the code of the asynchronous push. – Fogmeister Jan 13 '14 at 10:13
  • @Fogmeister you are correct, I have edited the code to use popToViewController animated. – Suhit Patil Jan 13 '14 at 10:13
  • Where are you running the async connection? Is it from viewDidLoad of C? Also, how quickly does the call back occur? Does the error come back instantly? If so you may still be in the animation of the previous transition. You might be better putting it in `viewDidAppear` of C instead of `viewDidLoad`. – Fogmeister Jan 13 '14 at 10:19
  • @Timothy Rajan where are you calling your sendAsynchronousRequest code? Means in which method? viewDidLoad or viewWillAppear? – Pradhyuman sinh Jan 17 '14 at 06:21

2 Answers2

2

I think your problem is that you are pushing asynchronously to the new ViewController.

You can't do any UI stuff in a background thread. It must all be in the main thread.

If you are running something in the background that may take a long time and then pushing to a new view controller then you must always go back to the main thread to push the view controller.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
-1

try

BViewController *BViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"BVC"];
[self.navigationController pushViewController: BViewController animated:YES];

Edit: Yes -pushviewcontroller will add controllers onto the stack. Please don't use it.

The -popToViewController is used to pop view controllers OFF the stack, down to one that already exists. But you have array of view controllers on the stack so you need to provide one of them as the argument like below code.

 [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];

Please refer this link for further info.

Community
  • 1
  • 1
Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
  • for (UIViewController *aViewController in allViewControllers) { if ([aViewController isKindOfClass:[messageViewController class]]) { UIViewController *myViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"messageview"]; [self.navigationController popToViewController:myViewController animated:YES]; } } – Timothy Rajan Jan 13 '14 at 09:48
  • This gave me the error - Tried to pop to a view controller that doesn't exist.' – Timothy Rajan Jan 13 '14 at 09:48
  • please use [self.navigationController pushViewController: BViewController animated:YES]; instead of popToViewController, it will work. see the answer above. – Suhit Patil Jan 13 '14 at 09:52
  • just a basic question correct me if I am wrong. whether pushViewController will add view controllers to the stack. or I am doing wrong by using PopToVcontroller. thanks – Timothy Rajan Jan 13 '14 at 09:56
  • @TimothyRajan yes, this will add a new VC to your stack so you will have A, B, C, D, B – Fogmeister Jan 13 '14 at 09:59
  • I believe pushViewcontroller will give me ABDEBDEBDEBDE and it goes on. whereas Pop will not allow the stack to grow. @Suhit- Can you please comment on this – Timothy Rajan Jan 13 '14 at 10:00
  • @TimothyRajan yes, you are correct. This is wrong as it will add a new BViewController to the stack instead of removing D and C. – Fogmeister Jan 13 '14 at 10:00
  • @Fogmeister - Thanks for this. Am I doing it right.NSLog gives me the correct stack items. But still I am getting the dreadful "Nested push animation". Whether this has to do with YES/NO parameter in animated? Thanks – Timothy Rajan Jan 13 '14 at 10:02
  • @TimothyRajan I commented on the question. – Fogmeister Jan 13 '14 at 10:03
  • @TimothyRajan I have edited my answer. please check. – Suhit Patil Jan 13 '14 at 10:14
  • @suhit - Thanks. I am already doing this. Still the error exists – Timothy Rajan Jan 13 '14 at 10:17
  • @Fogmeister - Have added the code [async block].This gets executed after say 5 seconds after view controller C is pushed to the stack – Timothy Rajan Jan 13 '14 at 10:18
  • Why 5 seconds? Is it using a Timer? – Fogmeister Jan 13 '14 at 10:20
  • that is the approximate time taken to compute and collect data from db . it is not static. It is dynamic. sometimes take even 2 seconds. sometimes 7 seconds – Timothy Rajan Jan 13 '14 at 10:25