inserting ViewController In between the stack of self.navigationController.viewcontroller - ios

I have three viewcontollers in my navigation controller. Now what i want to do just insert a view controller in between the array of self.navigationController.viewControllers.
As I checked the property viewControllers is not a readonly property So i think we can set it also.
thats why I used the below code to insert my ViewController in between the stack.
But unfortunately it doesn't modify the stack of self.navigationController.viewControllers.
So how can I insert and modify the stack. Also be sure that I don't want to pushViewcontroller.
CXSTransactionSelectionViewController *trxSelectionVc = [self.storyboard instantiateViewControllerWithIdentifier:#"CXSTransactionSelectionViewController"];
NSMutableArray *viewControllers = [self.navigationController.viewControllers mutableCopy];
[viewControllers insertObject:trxSelectionVc atIndex:viewControllers.count-2 ];
[self.navigationController setViewControllers:viewControllers animated:YES];
NSLog(#"%#",self.navigationController.viewControllers);

Try to do something like this:
NSArray * oldViewControllers = [self.navigationController viewControllers];
NSArray * newViewControllers = [NSArray arrayWithObjects:[oldViewControllers objectAtIndex:0], newVC, [oldViewControllers objectAtIndex:1],nil];
[self.navigationController setViewControllers:newViewControllers];

using this my problem is resolved
CXSTransactionSelectionViewController *trxSelectionVc = [self.storyboard instantiateViewControllerWithIdentifier:#"CXSTransactionSelectionViewController"];
[self.navigationController.viewControllers insertObject:trxSelectionVc atIndex:1 ];
NSLog(#"%#",self.navigationController.viewControllers);

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

ViewController being held in memory

I use the following code to switch between view controllers..(works fine) I have many view controllers too by the way Im not just switching back and forth between 2
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
MyTableViewVC *detailView = (MyTableViewVC *)[storyboard instantiateViewControllerWithIdentifier:#"MyTableViewVC"];
//pass data through to VC
[self presentViewController:detailView animated:NO completion:nil];
I see the memory use climbing as I transition between view controllers
So i did some research and realized Im not dismissing the previous view controller. I use the following code [self dismissViewControllerAnimated:NO completion:nil]; before I call presentViewcontroller: (I also tried using it after) and it doesn't work. If i use it after nothing happens.. using it before I get the following warning
Thread 1:EXC_BAD_ACCESS(code=1.... blah blah let me know if you need the rest
Ive also tried to do something like this..
[detailView presentViewController:detailView animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
What am I doing wrong?
Below is the code to remove VC from the navigation stack.
NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];
// [navigationArray removeAllObjects]; // This is just for remove all view controller from navigation stack.
[navigationArray removeObjectAtIndex: 2]; // You can pass your index here
self.navigationController.viewControllers = navigationArray;
[navigationArray release];
However note, by doing this you will have problem to go to previous VC as you are removng the previous VC from the stack.
As you are complaining about memory, I would say DOUBLE CHECK code once again and investigate where memory is getting used more. Incase if that object is not needed, release that object so that memory issue would not be there.
If you want to back to root view controller, you must use this code.
[self.navigationController popToRootViewControllerAnimated:YES];

back button doesn't go back

After pushing a ViewController using this code
UIViewController *vc = [[self storyboard] instantiateViewControllerWithIdentifier:#"frontCardViewController"];
[self.navigationController pushViewController:vc animated:YES];
I remove all ViewControllers I don't need anymore using this code
NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray:self.navigationController.viewControllers];
NSArray *array = [[NSArray alloc] initWithArray:navigationArray];
for (UIViewController *viewController in array) {
if ([viewController isKindOfClass:[RITCardViewController class]]) {
RSLog(#"Is kind of Class RITCardViewController");
[navigationArray removeObject:viewController];
}
}
self.navigationController.viewControllers = navigationArray;
The navigation array now looks like this:
"RITMainViewController: 0x10d81fc1>",
"RITDetailViewController: 0x10d847880",
"RITTestResultViewController: 0x113d0e090"
But the problem is that if the back button in the navigation bar is pressed now, it goes back to the second screen. But when the back button is pressed again it just stays on this screen. It seems to go trough all the screens I have removed, but doesn't show them.
What am I doing wrong?
Try something like this instead:
NSMutableArray *viewControllers = [#[] mutableCopy];
for (UIViewController *vc in self.nagivationController.viewControllers)
{
if (NO == [vc isKindOfClass:[RITCardViewController class]])
[viewControllers addObject:vc];
}
self.navigationController.viewControllers = viewControllers;
Make sure you don't corrupt the stack by removing the view controller you are currently on from the view controllers array. Assuming your current view controller is not an instance of RITCardViewController you should be fine. Otherwise, you'll have to make up for it in your code.

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?

self.navigationController is null after it is assign as RootViewController?

I created a new xcode project as View-based application, and I have a set of UIViewController(s) which I plan to use inside separate UINavigationController(s).
In ParentViewController.m before all the UINavigationController(s) and after all myViewControllers been initiated:
NSMutableArray *navControllers = [[NSMutableArray array];
for (id aVC in self.myViewControllers) {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:aVC];
//[aVC setNavigationController:navController];
[navController setNavigationBarHidden:YES];
[navController setToolbarHidden:YES];
[navControllers addObject:navController];
[navController release];
}
_navigationControllers = [[NSArray arrayWithArray:navigationControllers] retain];
_navigationControllers is retained as a member of ParentViewController, so I suppose all my navigation controllers initiated inside for-loop are kept by _navigationControllers so they won't be released or become nil, but when I try to use navigationController in MyViewController to push SomeOtherViewController, it doesn't work:
- (IBAction)pushDetailView {
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
I put a breakpoint before pushViewController:someOtherViewController, and "po [self navigationController]", the console tells me it is a nil reference.
I assumed that when I do
[[UINavigationController alloc] initWithRootViewController:aVC], the underlying mechanism would assign the navigationController as aVC.navigationController, because the Apple "View Controller Programming Guide for iOS" does the same without assigning navigationController to rootController.
Unless I unmark the second line of the for-loop //[aVC setNavigationController:navController];, the navigationController does not exist in aVC.
Am I misunderstanding the mechanism? Is there another solution for my case?
Thanks in advance!
_navigationControllers = [NSMutableArray array];
for (id aVC in self.myViewControllers) {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:aVC];
//[aVC setNavigationController:navController];
[navController setNavigationBarHidden:YES];
[navController setToolbarHidden:YES];
[navControllers addObject:navController];
}
// assuming index 0 navigation controller is with 'ParentViewController'
self.rootViewController = [_navigationControllers objectAtIndex:0];
check with this.

Resources