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

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];

Related

UINavigationController no animations anymore

I have a very weird problem with the UINavigationController on iOS 8, maybe someone encountered this already and can shed some light. I have 2 views: let's say view A and view B
I am using it like this:
view A [self.navigationController pushViewController:vc animated:YES];
push to a new view B [self.navigationController pushViewController:vc animated:YES];
push to a new view B [self.navigationController pushViewController:vc animated:YES];
push to a new view B [self.navigationController pushViewController:vc animated:YES];
push to a new view B [self.navigationController pushViewController:vc animated:YES];
push to a new view B [self.navigationController pushViewController:vc animated:YES];
return to view A [self.navigationController popToRootViewControllerAnimated:YES];
The problem is that if I play with this for 2 min and go through this like push-push-push-push-pop and again... at some time it stops animating, for either push and pop.
I checked the 1) view controllers they get deallocated on the pop to root, 2) I don't receive any memory warnings, 3) the navigation controller is the rootviewcontroller of the window so why this problem?
I can't find any explanation maybe someone has encountered this already. Also I am mentioning I am not using custom animations, just the plain native push and pop of a normal UIViewController, not even subclassing that so everything is plain native.
#kokos8998 try using
#interface AnimatorPushGalleryToGallery : NSObject <UIViewControllerAnimatedTransitioning>
and then in view A just add this and will control everything from view B either A->B or B->A (or in case you need something more custom add the same delegate in B as well)
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.delegate = self;
}
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
if(operation == UINavigationControllerOperationPush)
return [AnimatorPushGalleryToGallery new];
else if(operation == UINavigationControllerOperationPop)
return [AnimatorPopGalleryToGallery new];
return nil;
}

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];

How can I calculate number of current VC's in Navigation stack?

Any ideas? I want to know number of MyViewControllers.
use this
int count = [[navigationController viewControllers] count];
NSLog(#"controllers : %#", [navigationController viewControllers]);
NSLog(#"count : %d", count);
[navigationController viewControllers] which returns an array of controllers in navigation stack. using this array you can get the count of controllers.
You said "number of MyViewControllers" not number of viewControllers, so I assume you want to know how many of the viewControllers in the stack are instances of your own custom subclass. That's where the method [anyObject isKindOfClass] comes in. This snippet should help:
NSArray *viewControllerStack = [[self navigationController] viewControllers];
NSUInteger result = 0;
for(UIViewController *vc in viewControllerStack) {
if([vc isKindOfClass:[MyViewController class]] result++;
}
Is this what you're looking for?

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];
}
}

How to dismiss the PushViewController?

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)

Resources