How to dismiss the PushViewController? - ios

I have 10 viewControllers in my app. I have pushed all these viewControllers using pushViewController method of NavigationController on NEXT button clicked of each viewController.
I have used code for that as ;
[self.navigationController pushViewController:someView animated:YES];
Now i want to jump back to the rootViewController from the 10th child(viewController).
How can i do this ?
Please help me..
Thanks.

try to use ..
[self.navigationController popToRootViewControllerAnimated:YES];

Use this code:
[self.navigationController popToRootViewControllerAnimated:YES];

Try this
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:NO];//Use the desired index instead of 1 here
for just go back to last screen use this
[self.navigationController popViewControllerAnimated:YES]

NSInteger index = 0;
for (UIViewController *view in self.navigationController.viewControllers) {
if([view.nibName isEqualToString:#"RootViewController"])//put any `XIB name` where u want to navigate
break;
index = index + 1;
}
[[self navigationController] popToViewController:[[self.navigationController viewControllers] objectAtIndex:index] animated:YES];

To go back to the previous screen (last element of the view controller stack), pop the view controller:
[self.navigationController popViewControllerAnimated:YES];

you can use
[self.navigationController popViewControllerAnimated:YES]
for particular view ..

FOR SWIFT 4
self.navigationController?.popToRootViewController(animated: true)

Related

How can I pop to any view controller as I wish?

view controller A B C D
A -> B -> C-> D
popViewController only form D to C
popViewTopController only form D to A;
Any way can I pop to any view as I wish if I have 10 view controllers?
Thanks for everyone. will the popViewController pop to a new view Controller ?
Option 1: Select by class
To tell the navigationController to pop to a specific class, you can do as follows:
NSArray *allViewControllers = [self.navigationController viewControllers];
for (UIViewController *aViewController in allViewControllers)
{
if ([aViewController isKindOfClass:[B class]])
{
[self.navigationController popToViewController:aViewController animated:YES];
}
}
Take into account that you should only use this, if you are not pushing instances of the same class several times.
Option 2: Select by level
If you want to pop to a specific level, you can just select it by index at self.navigationController.viewControllers since it correspond to the levels. The first pushed UIViewController will be at index 0, the second at index 1 and so on:
NSArray *allViewControllers = [self.navigationController viewControllers];
UIViewController *aViewController = [allViewControllers objectAtIndex:level];
[self.navigationController popToViewController:aViewController animated:YES];
if you want to pop any view you want to change objectAtIndex:1,2,3..etc
it will pop to first,second etc... from the any views.
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
This is the method you are looking for (reference)
In Obj-c
- (NSArray *)popToViewController:(UIViewController *)viewController
animated:(BOOL)animated
You should pass in the view controller that you want pop to
Use the following UINavigationController method to go to any view controller on the current stack.
- (NSArray *)popToViewController:(UIViewController *)viewController
animated:(BOOL)animated
For example, if you are in a UIViewController and you want to pop back to the third one in the stack:
UINavigationController * nc = self.navigationController;
UIViewController * popToVC = [nc.viewControllers objectAtIndex:2];
[nc popToViewController:popToVC animated:YES];
SecondViewController *sec = [SecondViewController alloc] init];
[self.navigationController popViewController:Sec animated:YES];

Pop To RootView Controller issue

In my project I have some set of view controller added in a navigation controller like.
UIViewController1,UIViewController2,UIViewController3,UIViewController4,UIViewController5
consider UIViewController1 is my root view controller of navigation controller. after the navigation reaches UIViewContoller5 on button click I need to return back to my UIViewController1. So I'm writing following code.
- (void)popToRootViewControllerAnimated
{
NSLog(#"%#",[self.navigationController viewControllers]);
[self.navigationController popToRootViewControllerAnimated:NO];
}
In console it prints like
(
"<UIViewController1: 0x8e3fcc0>",
"<UIViewController2: 0x9a5d310>",
"<UIViewController3: 0x9a67b00>",
"<UIViewController4: 0x9162a00>",
"<UIViewController5: 0x9a84380>"
)
But after it finishes execution my view stays at UIViewController3. If I print [self.navigationController viewControllers] in my UIViewController3 it shows like,
(
"<UIViewController1: 0x8e3fcc0>",
"<UIViewController3: 0x9a67b00>",
)
What I m missing. Thanks in advance. Any help would be appreciated.
Try this:
UIViewController *firstVc = [viewControllers objectAtIndex:0];
[navCtrl setViewControllers:#[firstVc] animated:NO];
Try this hope this will solve your problem
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
this controller take you at zero(0) index of you all controllers.
Try this one
UIViewController *ctrl = [self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count -1];
[self.navigationController popToViewController:ctrl animated:YES];
Hope this will solve your issue.
Have you tried this.
-(void)backButtonAction
{
YourAppDelegate *app=(YourAppDelegate *)[[UIApplication sharedApplication]delegate];
for(UIViewController *vc in app.yourNavigationController.viewControllers)
{
if([vc isKindOfClass:[UIViewController1 class]])
{
[app.yourNavigationController popToViewController:vc animated:YES];
}
}
}
This solution works
for(UIViewController *objUIViewController in [self.navigationController viewControllers])
{
if([objUIViewController isKindOfClass:[UIViewController1 class]])
{
[self.navigationController setViewControllers:[NSArray arrayWithObject:objUIViewController]animated:YES];
}
}

Push a new ViewController and Pop the last one from NavigationStack

Hey Guys i want to push a new controller onto the navigation stack and then remove the controller where i pushed from.
Here is my Code :
WishDetailViewController *detailView = [self.storyboard instantiateViewControllerWithIdentifier:#"WishDetailView"];
detailView.transferWishID = [NSNumber numberWithFloat:[[response objectForKey:#"id"]floatValue]];
[self.navigationController pushViewController:detailView animated:YES];
[self.navigationController popViewControllerAnimated:NO];
Everthing works fine, but i got this message here inside the console :
2013-02-05 10:32:42.029 BWMApp[1444:1a603] nested pop animation can result in corrupted navigation bar
2013-02-05 10:32:42.392 BWMApp[1444:1a603] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
So what i am doing wrong and how can i prevent my app from throwing this error message ?
You can use setViewController. This example removes all and insert others, but give you the basic idea :)
NSMutableArray *viewCons = [[[self navigationController]viewControllers] mutableCopy];
[viewCons removeAllObjects];
[viewCons addObject:portraitTemp];
[viewCons addObject:self];
[[self navigationController] setViewControllers:viewCons];
There is no need to pop the "old" viewcontroller. The navigationController create a backbutton automatically. if you pop the viewcontoller from the stack there is no viewcontroller to "jump" back. This is the cause of message inside the console. The navigationController can't work correctly.
WishDetailViewController *detailView = [self.storyboard instantiateViewControllerWithIdentifier:#"WishDetailView"];
detailView.transferWishID = [NSNumber numberWithFloat:[[response objectForKey:#"id"]floatValue]];
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController pushViewController:detailView animated:YES];

How to "pop" several View controllers in UINavigationController Stack?

In my app I'm implementing UINavigationController. There are several UIViewControllers that are being pushed in the stack.
When I reach the last one, I wish to have (upon a user action) all the UIViewControllers be popped except for the first UIViewController. How do I do that?
I understand how to pop the last one, but how do I instruct all the previous ones to disappear as well?
You can try the popToRootViewControllerAnimated:, popToViewController:animated: and popViewControllerAnimated: messages of the UINavigationController class.
In your case it is really usefull to use popToRootViewcontrollerAnimated: as suggested by Irene, but if somebody need to pop exact number of controllers, then following code can be usefull:
- (void) popControllersNumber:(int)number
{
if (number <= 1)
[[self navigationController] popViewControllerAnimated:YES];
else
{
NSArray* controller = [[self navigationController] viewControllers];
int requiredIndex = [controller count] - number - 1;
if (requiredIndex < 0) requiredIndex = 0;
UIViewController* requireController = [[[self navigationController] viewControllers] objectAtIndex:requiredIndex];
[[self navigationController] popToViewController:requireController animated:YES];
}
}
Use
TravelViewController *travelView = [self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-3];
[self.navigationController popToViewController:travelView animated:YES];

Calling popToRootViewControllerAnimated after dismissModalViewControllerAnimated

I am working application in which i calling presentModalViewController and once finished(calling dismissModalViewControllerAnimated:YES) it should immediately call popToRootViewControllerAnimated.
But the issue is dismissModalViewControllerAnimated:YES is working properly but popToRootViewControllerAnimatedis not working after it.
The code is shown below:
[self.navigationController dismissModalViewControllerAnimated:YES] ;
[self.navigationController popToRootViewControllerAnimated:YES];
Try something like this:
[self.navigationController dismissModalViewControllerAnimated:YES] ;
[self performSelector:#selector(patchSelector) withObject:nil afterDelay:0.3];
-(void)patchSelector{
[self.navigationController popToRootViewControllerAnimated:YES];
}
It is not so neat but it should work.
UPDATE:
You should use
[self dismissModalViewControllerAnimated:YES];
instead
[self.navigationController dismissModalViewControllerAnimated:YES] ;
The object that is presenting the modal is the view controller, not the navigation controller.
If you have a navigation controller with a stack of UIViewControllers:
[self dismissModalViewControllerAnimated:YES];
[(UINavigationController*)self.parentViewController popToRootViewControllerAnimated:YES];
//UIViewController *vc = [[UIViewController new] autorelease];
//[(UINavigationController*)self.parentViewController pushViewController:vc animated:YES];
Assumes, that view controller in which called modal view controller has navigationController.
I ran into something similar to this. You need to make a copy of your self.navigationcontroller first and also retain yourself, so when you call the second pop, there is still a reference to the NC and you still exist.
// 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];
[navController pushViewController:someViewController animated:NO];
see : How can I pop a view from a UINavigationController and replace it with another in one operation?
I guess, you are not calling the
[self.navigationController popToRootViewControllerAnimated:YES];
in the target modal viewcontroller. check that.

Resources