Root view controllers and modal dialogs - iphone

In a custom UIViewController, if I have a member UINavigationController that I initialize with self as the root view, like this:
navController = [[UINavigationController alloc] initWithRootViewController:self];
then presenting a modal dialog does not hide the tab bar at the bottom of the screen. The result is that if the user switches to a different tab while a modal dialog is displayed, when they pop back to the tab that was displaying a modal dialog then subsequent calls to presentModalViewController do not display a modal dialog at all, even if I call dismissModalViewControllerAnimated as a result of the tab switch.
If I initialize the UINavigationController with out setting self as the root controller,
navigationController = [[UINavigationController alloc] init];
then the tab bar is hidden as expected. I've changed things in my program so that this isn't really an issue for me anymore, but I'm not sure that I understand why this is happening. Is it considered bad practice to have a navigation controller with self as the root, if the nav controller is going to be displaying modal dialogs?

I never added self as root controller
I always have some Controller that gets a NavigationController.view added to itself.
And the first ViewController that shall be displayed in the Navigation hierarchy I then add as the rootViewController. It's just another word for "first page" (in the beginning all the naming can be quite confusing).
Example in MyProjectAppDelegate.m:
UITableViewController *startScreen = [[UITableViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:startScreen];
[window addSubview:navController.view];
You also shouldn't mix UINavigationController with UITabBarController, if you want to have a tab bar in a navigationcontroller "page" you can build a custom UITabBarController.
This would show you how http://github.com/wiredbob/NavTab
(I had big problems in understanding all this view/controller nesting myself and this project really made the difference. You could say this was the code I really learned how to programm for iPhone/Mac with :DD )

Related

How to open a navcontroller from a non navcontroller view?

I'm coding an iphone app and I've an issue on how to manage views presentation. Indeed, when user starts the app a "home" View shows up containing a search form. When user presses a "search" button I want a method to open a navcontroller that displays the search results. I made another view containing a TableView with the purpose of serving as "results" View. I want the "results" view to allow user to go back to the "home" view (the search form) but I don't want the "home" view to have a navigation controller bar...
Any idea on how to solve this ?
Thx in advance,
Stephane
The easier way is just to hide the navigation bar on the 'home' view and show it back on the other view...
You have to create a UINavigation controller manually and present it modally as follows:
MapViewController *mapViewController = [[[MapViewController alloc] init] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mapViewController];
[self presentModalViewController:navController animated:YES];

How to use UItableView and UINavigationController in a "search" application ? Best practices

I would like to combine UITableView and UINaviationController in an app but as a newbie most apps I've seen just send you straight to the results view (UITableView). But, I guess a "normal" search application does not assume you have the results on the first screen. There should be a search form on first screen with input fields and a button that triggers the search process and show some results and navigation.
So, I'm just trying to replicate this normal behaviour in my app. I've already made the search form (no navigation shown on it, of course) and a seperated View called "ListingViewController" with its related View and containing a UITableView and where I think I should add the Navigation...The next idea will be to make a DetailViewController and possibly and ListingMapController to show the listing in a GoogleMap.
So, where I'm stuck at is how to add this Navigation Controller ?
Some suggested me to add it in the SearchViewController delegate...
But I don't want a navigation on search form of course...
Some suggested me to open the Navigation controller modally...
But, I"m also planning at adding a Tab Bar to allow user to see other informations (like About,etc...) and with a modal Nav controller I don't know if they will still see the bottom Tabbar...
Any suggestions? What do you think is of best practices especially to avoid my app of being rejected by Apple?
Thx in advance for reading and helping!
Stephane
You could init the navigationController with your View Controller as the root view Controller. Then hide the navigationBar (if you need to). You would then add the navigationController.view as the subview. This will basically look like the original view controller. Then you can pushViewController: animated: to push the results view Controller.
So, for example in your AppDelegate (or in the proper view controller):
Create a property and ivar for a UINavigationController and hook up its outlets in interface builder. Then set your search controller as the root view controller for the nav bar, and add it as a subview.
MySearchViewController* searchController = [[MySearchViewController alloc] init];
self.myNavigationController = [[UINavigationController alloc] initWithRootController:searchController];
[searchController release];
self.myNavigationController.navigationBarHidden = YES;
[self.window addSubview:self.myNavigationController.view];
[self.window makeKeyAndVisible];
Then of course in your searchController, you would simply say:
ResultsViewController* myResultsViewController = [[MyResultsViewController alloc] init];
//You may want to create another init method and pass in some arguments like an array:
// [[MyResultsViewController alloc] initWithResults:results];
then push the viewController
//This is in your search controller class
[self.navigationController pushViewController:myResultsViewController Animated:YES];
[myResultsViewController release];
from the results viewController, to get back you pop the view controller off of the navigationController view controller's stack.
//In results view controller perhaps in some IBAction for a back button:
-(IBAction)backButtonPressed:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}

how to create tabbar programmatically

HI all,
i am having navigation based application, in which i need too implement tab bars ,in one of view.
in one view i need 5 tabs, can any one please suggest me to create tab bars programmatically,, ? each tab should navigate to another xib.
Suggestions are always appreciated.
regards
Here is a sample code from Apple to create tab bar programmatically:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarController = [[UITabBarController alloc] init];
MyViewController* vc1 = [[MyViewController alloc] init];
MyOtherViewController* vc2 = [[MyOtherViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, nil];
tabBarController.viewControllers = controllers;
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
}
More here
It's worth noting that a tab bar controller implemented inside a navigation controller is unsupported by Apple. From the same doc linked to by vodhkang above:
Note: Although a navigation controller can be embedded inside a tab, the reverse is not true. Presenting a tab bar interface from within a navigation interface is potentially confusing for users. A navigation interface uses one or more custom view controllers to present an interface focused on one goal, which is usually the management of a specific type of data. By contrast, the tabs of a tab bar interface can reflect completely different purposes in an application and need not be related in any way. In addition, pushing a tab bar controller on a navigation stack would cause the tabs to be displayed for that screen only and not for any others.
So instead of using UITabBarController consider implementing a tab bar with a UIViewController as the tab bar's delegate.

How to add a UINavigationController to my UITableViewControllerSubclass?

My app is a tab bar application, which one of the tabs is a TableViewController instead of a viewController which works fine (the table displays great) but where and how do I add UINavigationController to it? :-)
You can do this 2 different ways... in IB or code. If I'm dealing with a TabBar I usually do it in IB. All you have to do there is is drag a NavigationController object where your tableview object currently sits... then just make your tableviewcontroller the first child of your new navigation object.
TabBarController
-(Tab Bar)
-NavigationController
--(Navigation Item)
--TableViewController
or
If you want to do it in code... I would just set it up within your app delegate (usually because a tab bar is at the highest point in your app... meaning it appears right away after loading):
// Create a tabbar controller and an array to contain the view controllers
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localViewControllersArray = [[NSMutableArray alloc] initWithCapacity:numberOfTabs];
// setup the view controllers
UINavigationController *myNavigationController;
myNavigationController = [[UINavigationController alloc] initWithRootViewController:myTableViewController];
// add to tab bar controller
[localViewControllersArray addObject:myNavigationController];
tabBarController.viewControllers = localViewControllersArray;
// add the tab bar to the window
[window addSubview:tabBarController.view];
You should then release the objects you just created since they will be retained by the TabBarController and Navigation Controller. Hope this helps
As Ryan noticed you can make it easily using IB. Here is how you can achieve this:
Launch Xcode and create new Tab Bar Application project.
Under resources group find MainWindow.xib and double click it to open in Interface Builder.
Next, select Tab Bar Controller object and open Inspector window (Command + Shift + I).
Notice "View Controllers" section in Inspector () then click on View Controller popup and change value from View Controller to Navigation Controller.
That's it! Now you can use your UITableViewController subclass inside this UINavigationController.

Set a navigation controller without an app delegate

I would like to show a Navigation Controller after clicking a button. Every tutorial assumes the navigation controller will be the first screen so it links it to the App Delegate, but App delegate only appears at MainWindow.xib.
How do you guys add a navigation controller to a view different than the MainWindow?
Thanks!
Here is some sample code to expand on Roger's answer. The following method is linked to some user interaction on the current view controller (to compose an email for example). This will give the compose view the navigation bar across the top instead of coding buttons inside your custom view.
-(void) composeButtonPushed: (id) sender {
ComposeViewController *controller = [[ComposeViewController alloc] initWithNibName:#"ComposeView" bundle:nil];
UINavigationController *composeNavController = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentModalViewController:composeNavController animated:NO];
}
UINavigationController is to navigate a heirarchy of views with UIViewControllers. If you don't have a root UIViewController, it won't work (and doesn;t make sense). If you do have a UIViewController, you simply send a - (id)initWithRootViewController:(UIViewController *)rootViewController init message to a new navigation controller passing in your UIViewController.