I came up with a workaround that looks up in a navigation controller's collection and find the offset between the existing and destination controller using name of destination controller and remove the in-between controller. Not sure if it is close to your need but give it a try:
- (NSArray *)navigateToViewController:(NSString *)destinationControllerName withControllers:(NSArray *)sourceControllers
{
NSMutableArray *controllers = [[NSMutableArray alloc] initWithArray:sourceControllers];
NSInteger sourceControllerIndex = [controllers count] - 1; // Value should be index oriented instead of position oriented.
NSInteger destControllerIndex = 0;
// Find position of destination controller (index oriented)
for (UIViewController *controller in controllers)
{
NSString *controllerName = NSStringFromClass([controller class]);
NSLog(@"class name: %@", controllerName);
if([[controllerName lowercaseString] isEqualToString:[destinationControllerName lowercaseString]])
break;
destControllerIndex +=1;
}
// If desired controller does not exists in the stack, do not proceed.
if (destControllerIndex == sourceControllerIndex)
{
return controllers;
}
// If destination is the same as source do not enter in this block
// If destination and source controllers have zero or no controllers in between do not enter in this block
// If destination and source controllers has few controllers (at least one) in between, go inside this block.
// Here "destControllerIndex + 1" shows, there is at least one controller in between source and destination.
else if(destControllerIndex + 1 < sourceControllerIndex)
{
NSLog(@"controllers in stack: %@", controllers);
// Start from the controller following the source controller in stack and remove it
// till the destination controller arrives
for (NSInteger iterator = sourceControllerIndex - 1; iterator > destControllerIndex; iterator--)
{
UIViewController *cont = [controllers objectAtIndex:iterator];
if(cont) {
[cont release]; cont = nil; }
[controllers removeObjectAtIndex:iterator];
NSLog(@"controllers in stack: %@", controllers);
}
}
return controllers;
}
and define it in some base controller:
-(void) popToViewController:(NSString *)controllerName withNavController:(UINavigationController *)navController
{
// STStatistics refers a singleton class of common functions.
NSArray *mArr = [STStatistics navigateToViewController:controllerName withControllers:navController.viewControllers];
navController.viewControllers = mArr;
// There should be more than one controller in stack to pop.
if([mArr count] > 1)
{
[navController popViewControllerAnimated:YES];
}
}
and here is how called:
[self popToViewController:@"NameOfDestinationControllerInNavStack" withControllers:self.navigationController];