30

I have a uinavigationcontroller. After logged in i want to remove viewcontrollers like RegisterViewController,LoginViewController etc from UInavigationcontroller stack..

I mean i have to remove a particular view controller from stack ? How its possible. ?

I checked this post

http://starterstep.wordpress.com/2009/03/05/changing-a-uinavigationcontroller’s-root-view-controller/

So we can take it into an array like

NSArray *allviewcontrollers= [(UINavigationController *)navigationController viewControllers];

But how to do further process.. This question is hunting me for long time..Please answer me ..Thanks in advance

S.P.
  • 5,427
  • 11
  • 56
  • 83

2 Answers2

86
NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray: navigationController.viewControllers];
[allViewControllers removeObjectIdenticalTo: removedViewController];
navigationController.viewControllers = allViewControllers;
Costique
  • 23,712
  • 4
  • 76
  • 79
  • Thank you for answering me.But i have doubt in second sentance. LoginViewController * loginViewController = [LoginViewController alloc]; [allViewControllers removeObjectIdenticalTo: loginViewController]; But it didn't worked.. But when i tried [allViewControllers removeObjectAtIndex:0]; it worked. I want something like that you answered. i also tried [allViewControllers removeObjectIdenticalTo: @"LoginViewController"]; But it didn't worked. Please clarify me. Thanks ... – S.P. Jan 20 '10 at 07:34
  • I had some doubts about how to remove the particular view..And i post a question for that and got the answer.. http://stackoverflow.com/questions/2100450/how-to-check-a-uiviewcontroller-is-present-in-uinavigationcontroller-stack/2101034#2101034 – S.P. Jan 20 '10 at 12:49
  • 1
    Somewhere in your code you created, say, the LoginViewController with +alloc and -initWithNibName:bundle:. That might be your app delegate, I don't know how your app is architected. Anyway, to reliably remove the controller you have to keep a reference to it (e.g. as an ivar in your app delegate). The "removedViewController" in the above snippet is just that reference. Yes you can traverse the array of view controllers looking for the controller of a particular class. But what if one day you'll have two or three of them as you extend your app? My 2 cents. – Costique Jan 20 '10 at 13:18
  • 1
    I understand that your method is the best way to remove a viewcontroller from uinavigation stack. Am very new to objective c. So confused with "reference to an object". I tried this one .. [allViewControllers removeObjectIdenticalTo: myDelegate.nonLogginedViewController]; Where in my Appdelegate i wrote @property (nonatomic, retain) NonLogginedViewController *nonLogginedViewController; and @synthesize nonLogginedViewController; Is it only needded to keep a reference to nonLogginedViewController ? Thanks in advance.. – S.P. Jan 21 '10 at 10:13
  • 4
    This works, though it's advisable to avoid doing it whilst animations to push or pop view controllers are going on. You will get logs like this: "Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted." – Johan Kool Jul 21 '11 at 08:11
  • @Costique Sir, Thanks a lot. it's too useful to me... Thanks again .. :) – V.J. Sep 24 '12 at 07:31
  • I am also doing like this but it is getting an error like "Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted." – Dev Nov 29 '12 at 04:41
  • Elaborating on @JohanKool's comment, you should avoid doing this while animations are taking place. The simplest place to do this is in `viewDidAppear`. However, be warned that this method may be called multiple times so you should take the appropriate steps for safety and only remove the view controller(s) once. – devios1 Jun 18 '15 at 21:43
  • this works to some extent. The navigation items stack does not get affected. When pressing Back, you will get view controllers having the Title of the views which you have removed this way. To avoid this, just use pop and push (if necessary, pop everything and push back only what you want, without animating) – Radu Simionescu Sep 15 '15 at 10:29
1

Here is my solution. You can set the tag or a fixed property to your viewcontrollers, then you could traverse the uinavigationcontroller stack to search the target viewcontroller(vcToRemove) and remove it. This could be safer. The code:

NSInteger tag = vcToRemove.wvTag;
NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray: vcToRemove.navigationController.viewControllers];
        int i = 1;
        for (i = 1; i <=[allViewControllers count]; i++) {
            UIViewController *vc = [allViewControllers objectAtIndex:i];
            if ([vc isKindOfClass:[MyWebViewController class]]) {
                if (((MyWebViewController *)vc).wvTag == tag) {
                    [allViewControllers removeObjectAtIndex:i];
                    break;
                }
            }
        }

        vcToRemove.navigationController.viewControllers = allViewControllers;
Jie Liu
  • 11
  • 1