Adding a Navigation Controller to an existing project - iphone

I'm sure this is something stupid (it nearly always is when I finally decide to post :) but I can't seem to figure it out, so here goes:
I have a project which contains a UITableViewController (among others) which works fine, but I decided I wanted to enable editing on it and that means it needs to be contained within a UINavigationController. So I added one to the project, set it up so the view is loaded from my table view controller nib, and... it comes up empty. Just a white view with the blue nav controller bar up top.
I've verified that the table view is getting loaded - viewDidLoad runs, at least. Clearly something's not hooked up, probably something in IB, but I just can't seem to see it.
Any suggestions?

In your AppDelegate.h class
UINavigationController *navigationController;
In your AppDelegate.m class
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
navigationController = [[UINavigationController alloc]
initWithRootViewController:viewController];
[self.window addSubview:navigationController.view];
}
Try this. It may solve your problem.

Change the class inheritance from UITableViewController to uiviewcontroller. In the xib put the table view and attach it with an iboutlet for uitableview, set the two required protocols for table view and hope that is done if I am not missing anything.

It seems you forget to pass nib name in the interface builder. Try selecting viewControler inside UINavigation Controller in interface builder and set the nib name and class there. If you by-mistake set the nib name and class name on UINavigation controller remove the nib name and class from there.

Its to use the navigation bar rather than using navigation controller since it can fulfill your requirements.
Just place the navigation bar in Xib file & add an action button event over the button.

Related

iPhone Dev - Where is RootViewController instantiated in a Navigation-based application?

I can't seem to find where it's actually instantiated. I looked in the myProjAppDelegate.m and saw this:
self.window.rootViewController = self.navigationController;
But it says that the window's rootViewController property is really just a UIViewController, not a UITableViewController, which is what the RootViewController.m class is a subclass of. I wrote a custom method in my RootViewController.m and tried to call it on self.navigationController in myProjAppDelegate.m and got a SIGABRT, so it seems like this is not it. Can anyone help me out?
It's not visible in code. Your MainWindow.xib contains a Window and a Navigation Controller which are connected via outlets to your AppDelegate.
Both the Window and the Navigation Controller get instantiated when the application loads the .xib files.
Inside the Window (in the MainWindow.xib) is a RootViewController, that is the RootViewController you are talking about.
Regarding the class, UITableViewController inherits from UIViewController.

Changing the ViewController in NIB

I created a VIEW based application named ktemp1. and It generated .., ktempView1Controller.h and ktempView1Controller.m..,
Later I created one more view.., say "ktemp2ViewController.h" and "ktemp2ViewController.m".
I have a navigationController defined in AppDeligate with rootViewController set as ktempView1ViewController., Having done this All Works fine..
BUT, What I want is to set ktemp2ViewController as the rootViewController.
To do this, I am changing the ViewController class in MainWindow.Xib to ktemp2ViewController and changing the rootViewController to ktemp2ViewController.., But whenever I run the application, I am getting ktempView1 as the rootView and even when I click on the ktemp2ViewController in MainWindow.Xib , the view in IB is getting loaded from ktemp1ViewController...
Can anyone guide me ?
In the standard apple template, you will find something like this in your AppDelegate didFinishLaunching.
window.rootViewControlller = self.viewController;
There should be only a single rootViewController in your application and you should not attempt to set it frm anywhere else than the AppDelegate.
So what is relevant in your case, is the viewController property of the appDelegate. When you look at your MainWindow.xib, you need to make sure it contains a kTempViewController2 and that is wired to your AppDelegate.viewController property (the AppDelegateshould be the MainWindow.xib owner).
I hope you have Navigation controller in your mainWindow.xib.
Explore it and you could see a view controller (root view controller) and other view controller, if any.
Select the root view controller, set its class type and specify its nib name.

iPhone Obj C - 2nd XIB How to configure a Nav Controller and View Controller

Still learning Obj-C slowly... forgive the dumb questions...
On my 1st XIB I have the App Delegate, Nav Controller and several view controllers. Along with that I have several buttons that calls a 2nd or 3rd or subsequent XIB.
The subsequent XIBS all have buttons which display views.
So on the 2nd+ XIB I have configured it in the .h as an UIViewController however I am guessing I need to make it something else like the primary .h is an AppDelgate.
So right now the XIB wants the view set, but I don't want it to go to a view, I want it to go to the view controller... I think??
Maybe I am still going about this all wrong. I need the primary menu to call the next menu (2nd XIB) which in turn calls various views. In my Java Android app I have about 70 classes, and guess and about 45 views so I am guessing again that I do in fact need the multiple XIBS.
So the question is how do I set up the additional XIBs? Are they AppDelegates or what?
Does that change the way I call the 2nd XIB?
The XIBs or the UIViews (or it's subclasses) are just the facial make up.
For the actually programming part, you deal directly among the "controllers" classes for these views.
View controllers that you make can have an XIB attached to them. But the behavior of how and when the view is shown or hidden, is all handled by the view controller itself.
So to come to the point, if you want to have a navigation bar on the top of you app (assuming that it's a simple app wanting to show many views with a navigation bar):
Create a UINavigationController instance in your applicationDidFinishLaunching: method in the app delegate:
// Assuming that mainViewController is the first controller + view for your app.
navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
[window addSubview:navigationController.view];
This will automatically add a navigation bar to your views. You don't need to add them manually in XIB or anywhere else. Now how you draw/implement mainViewController, is up to you.
When you want to show another view from within mainViewController, you should call:
AnotherViewController *anotherViewController = [[[AnotherViewController alloc] init] autorelease];
[self.navigationController pushViewController:anotherViewController animated:YES];
This will "push" your new view (from anotherViewController instance) into your navigation structure, which will automatically add a back button on the top.
Hope this helps clear the scene of how it works, a bit.
If you have doubts, comment about it. Have a great day!

Help how to load UINavigationViewController from UIViewController

Here goes stupid question again :(
I am trying to create a sample app that loads UIViewController when the app loads and the view contains a button to load UINavigationViewController.
Now I created a project with "Window-based Application" and added "RootViewController" in the project with .m, .h, and .xib.
Next I added a view and a button in the "RootViewController.xib" file and it runs ok. After that, I added "UIViewController subclass" file naming "NavViewController" with .h, .m and .xib files.
Also I added - (IBAction)buttonPressed:(id)sender function in the "RootViewController" classes to load NavigationViewController.
Here is the code of the "buttonPressed:".
- (IBAction)buttonPressed:(id)sender {
NavViewController *navViewController = [[NavViewController alloc] initWithNibName:#"NavViewController" bundle:nil];
self.navController = navViewController;
[self.view insertSubview:navViewController.view atIndex:0];
[navViewController release];
}
When I "build and go," it runs fine initially until I press the button. When I press button, program terminates it.
What am I doing wrong? Please help...
Thank you.
What are you doing wrong? Designing your app in a non-standard way - you are not supposed to be able to do this - the NavigationController is in charge!
Why would you have a button that then adds a navigation controller? - it goes against the user interface guidelines. I found it hard to get to grips with the interface guidelines to begin with but you really must because it will make your app so much more usable.
If you need a navigation controller then add it to the view to begin with - or create a new view with the navigation controller. Honestly try it out and you will feel the user interface feels much better.
If you really want a button that adds a navigation controller to the window then do the following:
Keep a reference to the AppDelegate in your code
Use this reference and pass in your current view controller to a method called reloadMainViewWithNavBar:(UNViewController*) viewController
This new method should remove the old mainViewController and create a NavigationController
using your viewController as the root view conroller
add the navigation controller view to window view
The navController has no view set in the nib. A UINavigationcontroller needs a root view. In the nib, connect the navigation controller to a another view controller.
In addition to the fix mentioned above, what you really want to do is create the first view controller contained in the navigation controller - but hide the navigation bar until the button press causes it to unhide. You cannot easily add a navigation controller to a view you are in.

Loading UINavigationController from another nib automatically by UITabBarController

I think I've found the cause: Document Info window in IB has a warning: "'Selected Navigation Controller (Second)' has nib name property set to 'SecondView.nib', but this view controller is not intended to have its view set in this manner."
Bummer.
I've built nib in Interface Builder that has UITabBarController at top level and switches between UINavigationControllers.
It works fine when everything is in a single nib file, but I'd like to use separate nib files for UINavigationControllers.
Starting with Apple's TabBar template, if I just change class of SecondView to UINavigationController, it all breaks:
and all I get is this:
// imgur has lost the image, sorry //
Is it possible to have separate file for UINavigationController without programmatically setting everything?
I would like TabBarController to handle loading and unloading of nibs.
Simply swap the UINavigationController with the FirstViewController.
So the hierarchy should be like this:
Tab bar controller
-----Tab bar
-----Navigation Controller
----------First View Controller
---------------Navigation Item
----------Tab bar item (First)
-----Navigation Controller
----------Second View Controller
---------------Navigation Item
----------Tab bar item (Second)
You set the nib of First View Controller in the inspector to the nib file containing the actual view objects (Since you are trying to split them into separate files, which is a good thing).
You have one tab, that tab has a navigation controller which loads First View Controller as its root view.
Done.
I haven't tried setting up UINavigationController via IB. I have multiple screens, each is stored in separate xib and there's a corresponding class that extends UIViewController. In applicationDidFinishLaunching I initialize UIViewControllers using xib's but then manually create UINavigationController, add navigation controller's view to window and push first view to navigation controller.
Not sure if that helps.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
navigationController = [[UINavigationController alloc] init];
FirstViewController * viewController = [[FirstViewController alloc]
initWithNibName:#"FirstView"
bundle:nil];
[navigationController pushViewController:viewController animated:NO];
[viewController release];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
}
Above FirstViewController extends UIViewController, in IB you create your view then set File's owner class to your class (e.g. here FirstViewController) and connect the File's owner view to the UIView's view.
I believe you are looking for something like this. You would replace "whatever" with the name of you second nib file.
newNavController = [[UINavigationController alloc] initWithNibName:#"whatever" bundle:[NSBundle mainBundle]];
First, it looks like you have your UITabBarItems under the navigation controllers instead of directly under the UITabBarController. That may be part of your problem.
Second, when you add a UITabBarController in IB and and click on its icon in your list of top-level objects (your first screenshot), the attributes inspector will allow you to change the type of view controller for each of the tabs. Using this, you can change them all to navigation controllers, if you wish. Also, since you wanted to load custom views and view controllers from other nibs, if you look at the "View Controller" section at the bottom of the attributes inspector, you can select a nib from your project to load the view from. Assuming that nib's "File's Owner" is set to your UINavigationController subclass, it should all work fine.
All of this without a large amount of coding work, either. Let me know if you'd like screenshots for what I'm talking about in case you can't find these panels.
I found the same warning.I have kept all view controller in separate xib files. I got rid off it by removing .nib name and keeping it empty.