popping and pushing view controllers in same action
MapsViewController *aViewController = [[MapsViewController alloc]
initWithNibName:@"MapsViewController" bundle:nil];
// 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 this controller and replace with another
[navController popViewControllerAnimated:NO];//not to see pop
[navController pushViewController:aViewController animated:YES];//to see push or u can change it to not to see.
Or
MapsViewController *aViewController = [[MapsViewController alloc]
initWithNibName:@"MapsViewController" bundle:nil];
UINavigationController *navController = self.navigationController;
//Get all view controllers in navigation controller currently
NSMutableArray *controllers=[[NSMutableArray alloc] initWithArray:navController.viewControllers] ;
//Remove the last view controller
[controllers removeLastObject];
//set the new set of view controllers
[navController setViewControllers:controllers];
//Push a new view controller
[navController pushViewController:aViewController animated:YES];
In Swift:
let newVc = UIViewController()
var vcArray = self.navigationController?.viewControllers
vcArray!.removeLast()
vcArray!.append(newVc)
self.navigationController?.setViewControllers(vcArray!, animated: false)
In case newVc exists in a Storyboard:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newVc = storyboard.instantiateViewControllerWithIdentifier("YourViewControllerIdentifier") as! UIViewController
var vcArray = self.navigationController?.viewControllers
vcArray!.removeLast()
vcArray!.append(newVc)
self.navigationController?.setViewControllers(vcArray!, animated: false)
Taken from https://stackoverflow.com/users/1619554/tomer-peled 's solution, so others can find it more easily.
This appears to be the best way to do it for iOS8:
UIViewController *newVC = [[UIViewController alloc] init]; // Replace the current view controller
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
[viewControllers removeLastObject];
[viewControllers addObject:newVC];
[[self navigationController] setViewControllers:viewControllers animated:YES];
Swift 4 :
self.navigationController.setViewControllers[]..
doesn't worked out for me. But I am able to solve the issue by holding a navigation controller in an instance variable and do push/pop operation. Thus, silently able to change controller without glitch.
guard let navigationVC = self.navigationController else { return }
navigationVC.popViewController(animated: false)
navigationVC.pushViewController(myNewVC, animated: false)
You can use this code to pop or push your controller.
For objective c
bool alreadyPushed = false;
//Check if the view was already pushed
NSMutableArray *viewControllers;
if ( (viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers])) {
for (UIViewController *aViewController in viewControllers) {
if ([aViewController isKindOfClass:[YourControllerName class]]) {
NSLog(@"pop your view controller");
[self.navigationController popToViewController:aViewController animated:YES];
alreadyPushed = true;
break;
}
}
}
//Push Fresh View
if( alreadyPushed == false) {
NSLog(@"push your view controller");
YourControllerName *YourControllerObject = [[YourControllerName alloc]initWithNibName:@"YourNibName" bundle:nil];
[self.navigationController pushViewController:YourControllerObject animated:YES];
}
For Swift
var alreadyPushed = false
//Check if the view was already pushed
if let viewControllers = self.navigationController?.viewControllers {
for viewController in viewControllers {
if let viewController = viewController as? YourControllerName {
self.navigationController?.popToViewController(viewController, animated: true);
print(" Push Your Controller")
alreadyPushed = true
break
}
}
}
if alreadyPushed == false {
let YourControllerObject = self.storyboard?.instantiateViewControllerWithIdentifier("YourControllerIdentifire") as! YourControllerName
self.navigationController?.pushViewController(YourControllerObject, animated: true)
}