Proper way to push a view controller - iphone

I have a UIViewController that I wish to push onto the stack, however, when I call [viewController release] on it after I push it, any time I pop it off of the stack however, I get various errors pertaining to deallocated instances of the view controller. Here is an example of an implementation:
RootViewController *rootViewcontroller = [[RootViewController alloc] initWithNibName:#"RootViewController"
bundle:nil];
[self.navigationController pushViewController:rootViewController animated:YES];
[rootViewController release];

In the code that you showed you create rootViewController but actually push personsViewController. Typo? Or did you paste the wrong code?

Your RootViewController instance is "rootViewcontroller" but you're pushing "rootViewController" (notice the 'C'?).

Related

Can I not 'pushModalViewController'?

I have a UIViewController class and a second which I want to push modally preferably. However I can't seem to call [self pushModalViewController:...], how come?
What requirements do I need to meet to be able to do so?
I am doing this and getting a black view pushed:
vc = [[ViewController alloc] init];
[vc setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:vc animated:YES];
I have made my view controller in my storyboard and given it a custom class. I am trying to present this view modally via this class as seen in my code.
Any help much appreciated, thanks.
'push' and 'modal' don't belong together in the same thought. You can:
present a modal view controller, preferably using -presentViewController:animated:completion:, which is the modern replacement for -presentModalViewController:animated:
push a view controller onto the navigation stack, assuming that you're using a UINavigationController. To do that from a view controller, use:
[self.navigationController pushViewController:foo animated:YES];
You're actually looking for [self presentModalViewController:myViewController.view animated:YES]
How are you initing this viewcontroller. From the posted code, I assume it is being initialized to a blank view.
Maybe you can init it from a nibname or something?
vc = [[ViewController alloc] initWithNibName:#"NibName" bundle:nil];
[vc setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:vc animated:YES];
Also another thing to note, if this is a custom class and no nib file, is there any code in initWithCoder? How does the viewDidLoad looks like?

don't understand how to use navigation controller in iphone

I'm extremly new to iphone and I have the following misunderstanding.
All over internet the tutorials about how to use NavigationController programatically it says:
NavigationController must be declared in applicationDidFinishLaunching and must be init with a root.After that you can add views to it.
I have this:
A UIViewController class meaning(AdiViewController.h, AdiViewController.m and AdiViewController.xib) and no Delegate file meaning no applicationDidFinishLaunching method.
What I wanna do is from my class-AdiViewController when pressing a button to go to another view.
I understand that I need a NavigationController which should retain my views having the root AdiViewController.
But my problem is where should I initializate that NavigationController in viewDidAppear??...cause I don't have the Delegate files.
If you could provide a minimal example with this small issue of mine it would be great.I'm sure that for those how are senior this is nothing but still I don't get it.Thanks
NavigationController must be declared in applicationDidFinishLaunching -> this is not true.
In your AdiViewController if you have button when you push that button you want to load navigation Controller right ?
// Hook this IBAction to your button in AdiViewController
- (IBAction)pushNavController
{
AnotherViewController* rootView = [[AnotherViewController alloc] initWithNibName:#"Anotherview" bundle:nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:rootView];
[rootView release];
[self presentModalViewController:navController animated:YES];
[navController release];
}
If you are in AnotherViewController i.e., you are in root view controller of Navigation controller. You need to push and pop view controllers from there. For example if you have a button in AnotherViewController:
// push next view controller onto navigation controller's stack
- (IBAction)pushNextViewController
{
NextViewController* nextView = [[NextViewController alloc] initWithNibName:#"NextView" bundle:nil];
[self.navigationController pushViewController:nextView animated:YES];
[nextView release];
}
// Similarly if you want to go back to AnotherViewController from NextViewController you just pop that from navigation controller's stack
- (IBAction)pushNextViewController
{
[self.navigationController popViewControllerAnimated:YES];
}

viewDidDisapper won't call

I have uinavigation controller with a view controller named VC1,now i have a button in VC1 that when i click on him i go to view controller VC2,this is how i bring VC2 to screen :
VC2 *tmp = [[VC2 alloc]init];
[[self navigationController] pushViewController:tmp animated:YES];
[tmp release];
now when i click in VC2 on the back button of the navigation to return to VC1 its work but i put in VC2 viewDidDisappear and viewWillDisappear methods,and when i click on the back button this function won't called, any one have any idea?
You may call the view[..] methods manually from the UINavigationControllerDelegate callbacks, however the easiest way to ensure that the methods are called by the super implementation of the UINavigationController is just to call them manually once when the UINavigationController is allocated.
See my answer here: iPhone viewWillAppear not firing
So immediately after you have called navController = [[UINavigationController alloc] init.., make sure to call
[navController viewWillAppear:NO];
[navController viewDidAppear:NO];
[navController viewWillDisappear:NO];
[navController viewDidDisappear:NO];
This should ensure events are correctly forwarded to each view controller in the future.
If you want to call the viewWillDisappear/viewDidDisappear methods, your view controller has to do that manually before popping itself off the nav stack. Have a look at this
,you might get an idea how to do it.

NavigationController initWithRootViewController dealloc

I have some pretty simple code where I am using a UINavigationController and adding a rootViewController. After some processing has occurred I want to pop off the current view controller and replace it with another one. This seems to work fine, but my original view controller does not dealloc. I set a breakpoint in it's dealloc and it never gets hit. Below is my code. Not sure why happens. Just for testing if I release startController twice it does go away.
StartViewController *startController = [[StartViewController alloc] initWithNibName:#"StartViewController" bundle:[NSBundle mainBundle]];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:startController];
[nav pushViewController:startController animated:NO];
self.navController = nav;
[startController release];
[nav release];
Thanks any help.
Your ultimate goal is to bring the view controller's retain count to zero. So make sure that everything the view retains is released and anywhere the view is retained also release.
Please check the following possible causes:
Make sure you pop the view controller from the navController if you have a custom back button. The default Back button will work fine.
Make sure that all your IBOutlets are set to nil in viewDidUnload
- (void)viewDidUnload
{
[super viewDidUnload];
self.webView = nil;
}
If your view is an observer to a model class to receive events
For example
model.addObserver(myView);
and sure to also do
model.removeObserver(myView);
I hope this helps.
It looks as though your self.navController has got a holding reference to it. maybe put
self.navController =nil;
somewhere appropriate, so that when the view has been popped it is released.
I was trying to pop off the root view controller. I instead used the setViewControllers message from the UINavigationController object to replace all my view controllers.

access methods and variables in first navigation controller from pushed view

I normally use UIViews to make my apps - but this one I am using a navigationcontroller. I am pushing a view to the top where I want to add items to an array. However, I cannot access the main navigation controller methods etc. Here's the set up
1) AppDelegate adds navigation controller
[window addSubview:navigationController.view];
2) In RootViewController I push a new UIView
AddNewViewController *addNewViewController = [[AddNewViewController alloc] init];
[self presentModalViewController: addNewViewController animated:YES];
3) From the AddNewViewController I then want to access the main RootViewController - but cannot seem to access anything. All the methods etc are declared as I've done it before (using UIViews). This code cannot find anything in the RootViewController.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.navigationController myFunction];
I have myFunction in the RootViewController.h file. I have used this method before, but never with a navigation controller. I guess it's something to do with hte stack - but I cannot find out what I've done wrong!
Help is much appreciated!!
* UPDATE *
I have now used
AddNewViewController *addNewViewController = [[AddNewViewController alloc] init];
[self.navigationController pushViewController:addNewViewController animated:YES];
to push the view controller. In my code, I am trying to access the tableview to reload it with the following code
[self.navigationController.mainTableView reloadData];
but the mainTableView is not accessible. I have declared and sync'd it but still cannot see it. I also tried to loop through and use the element[0] of the stack (as below) but didn't get anywhere with that either!
NSArray *controllers = [[NSArray alloc] initWithObjects:self.navigationController.viewControllers, nil];
UIViewController *tmpController = [[UIViewController alloc] init];
tmpController = [controllers objectAtIndex:0];
First of all,
[self presentModalViewController: addNewViewController animated:YES];
does something different than
[self.navigationController pushViewController:addNewViewController animated:YES];
The names of those methods should speak for themselves.
And appDelegate.navigationController is not your rootViewController. It is the UINavigationController. You can get an NSArray of viewControllers attached to the navigationcontroller with self.navigationController.viewControllers. Item at index 0 should be your rootViewController.
If you push the viewController on the navigationControllers stack there is no need to use the appdelegate. You can access the navigationController with self.navigationController.