I want to push a view controller onto the stack, then pop the first one that pushed the new one.
-(void) someMethod {
MegaSuperAwesomeViewController *tempVC = [[MegaSuperAwesomeViewController alloc] init];
[self.navigationController pushViewController:tempVC animated:YES];
[tempVC release];
// pop this VC, how?
}
EDIT: turns out I can pop back 2 view controllers instead once finished with the new VC. Still not what I wanted exactly, but it works. The downside is I need to set a flag to indicate that the covered view is completed.
Here's a technique of popping back two view controllers, which has a similar problem of yours of the current view controller and its navigationController property going away as soon as you do the first pop:
// pop back 2 controllers on the stack to the setup screen
//
// locally store the navigation controller since
// self.navigationController will be nil once we are popped
//
UINavigationController *navController = self.navigationController;
// retain ourselves so that the controller will still exist once it's popped off
//
[[self retain] autorelease];
// Pop back 2 controllers to the setup screen
//
[navController popViewControllerAnimated:NO];
[navController popViewControllerAnimated:YES];
alternatively, you can directly "party" on the navigation controllers stack of view controllers:
setViewControllers:animated: Replaces
the view controllers currently managed
by the navigation controller with the
specified items.
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated Parameters
viewControllers The view controllers
to place in the stack. The
front-to-back order of the controllers
in this array represents the new
bottom-to-top order of the controllers
in the navigation stack. Thus, the
last item added to the array becomes
the top item of the navigation stack.
animated If YES, animate the pushing
or popping of the top view controller.
If NO, replace the view controllers
without any animations. Discussion You
can use this method to update or
replace the current view controller
stack without pushing or popping each
controller explicitly. In addition,
this method lets you update the set of
controllers without animating the
changes, which might be appropriate at
launch time when you want to return
the navigation controller to a
previous state.
If animations are enabled, this method
decides which type of transition to
perform based on whether the last item
in the items array is already in the
navigation stack. If the view
controller is currently in the stack,
but is not the topmost item, this
method uses a pop transition; if it is
the topmost item, no transition is
performed. If the view controller is
not on the stack, this method uses a
push transition. Only one transition
is performed, but when that transition
finishes, the entire contents of the
stack are replaced with the new view
controllers. For example, if
controllers A, B, and C are on the
stack and you set controllers D, A,
and B, this method uses a pop
transition and the resulting stack
contains the controllers D, A, and B.
Availability Available in iOS 3.0 and
later. Declared In
UINavigationController.h
So, to "disappear" the view controller directly under you on the navigation stack, in your view controller's viewDidLoad, you could do this:
NSMutableArray *VCs = [self.navigationController.viewControllers mutableCopy];
[VCs removeObjectAtIndex:[VCs count] - 2];
self.navigationController.viewControllers = VCs;
I had trouble figuring this out also so I wanted to share how I got this to work.
Let's say you have a stack of VCs VC1 being the root then you push VC2 and from VC2 you want to push VC3 but once pushed you don't want the user to go back to VC2 but rather to VC1 (the root). The way to do that is:
//push VC3 from VC2
[[self navigationController] pushViewController:VC3 animated:YES];
// now remove VC2 from the view controllers array so we will jump straight back to VC1
NSMutableArray *viewHeirarchy =[[NSMutableArray alloc] initWithArray:[self.navigationController viewControllers]];
[viewHeirarchy removeObject:self];
self.navigationController.viewControllers = viewHeirarchy;
Hope this helps someone else
Thanks Bogatyr about the tip on 'party on the viewcontroller array for the navcontroller'. I just replaced the entire stack with the one viewcontroller I want to change to, and then log out all the viewcontrollers in the stack to make sure its the only one! Worked great - thanks!
RatingsTableViewController *newViewController = [[RatingsTableViewController alloc] init];
NSMutableArray * newVCarray = [NSMutableArray arrayWithObjects:newViewController, nil];
self.navigationController.viewControllers = newVCarray;
[newViewController release];
NSMutableArray *allControllers = [[NSMutableArray alloc] initWithArray:self.navigationController.viewControllers];
for (id object in allControllers) {
NSLog(@"name VC: %@", object);
}
[allControllers release];
-(void)popToSelf{
NSArray *array = [self.navigationController viewControllers];
for (int i = 0 ; i < array.count ; i++) {
UIViewController *currentVC = [array objectAtIndex:i];
if ([currentVC isKindOfClass:[YourViewControllerClass class]]) {
[self.navigationController popToViewController:[array objectAtIndex:i] animated:YES];
}
}
}