Setting up and using the UINavigationController class in Objective-C - objective-c

I am trying to use the UINavigationController class in Objective-C, but I am having a difficult time understanding how it should work.
Basically, I have my app. I want to use the UINavigationController to show a hierarchy of data stored in an NSArray. I currently have this data being presented in UITableView. I want to make it so a user can click on a row of the table view and be taken to more specific data about the row they just clicked. I think a UINavigationController is perfect for this.
However, my understanding of MVC in the context of Objective-C is not that good and I am confused about how to do this. I want the UINavigationController to only show up in the left half of my iPad app and I would also like the ability to hide it at times. So how do I configure this?

This sounds like the correct usage for a navigation controller.
What you will need to do is create your navigation controller and populate the root view with your view controller containing the table view. In your didSelectRowAtIndexPath you would push the detail view onto the stack. All the navigation will be set up to go back for you.
Most likely in your AppDelegate:
ListViewController *theView = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
UINavigationController *navView = [[UINavigationController alloc] initWithRootViewController:theView];
[theView release];
[window addSubview:navView.view];
[window makeKeyAndVisible];

Related

Why Can't Push My New ViewController?

So, I have a main menu, and when I click one button from the main menu, I want to display another ViewController, so I create a NavigationController, I add the ViewController to this NavigationController and try to display, but nothing happens.
My code to push my new ViewController:
SubMenuViewController *subVC = [[SubMenuViewController alloc]initWithNibName:#"SubMenuViewController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] init];
[nav pushViewController:subVC animated:YES];
nav = nil;
This code is called in the MainViewController, when one button is pressed...
My SubMenuViewController creates a SplitViewController, with also two NavigationController, one for the table of the left, and the other for the table of the right, but these can't be the problem, right?
If you need more information to help me, please, tell me
The UINavigationController that you are creating needs to be part of your view controller hierarchy. As you have it, you've just created it but not added it to anything. You'd probably be better served to create it at the top of your hierarchy and push sub-views onto it rather than trying to create it on the fly.
I already kind of solved, even thought now can't go back, but can push one new ViewController. In the AppDelegate, I forgot to put this:
self.window.rootViewController = nab;
Now it push another ViewController. Thanks for the help highlycaffeinated

Can we put navigationcontroller in MasterView in iPad Application?

I have worked mostly on iPhone apps. Now I need to build an iPad app. In that I need to put NavigationController in the MasterView of the Master Detail View of the iPad as we do in the UITableView in the iPhone. I mean when user selects a particular row it should navigate to another tableview with newly filled data. and user can go to the previous by pressing back button. Also On each selection I need to make change of image in the detail view.
I dont have any idea to achieve this.
Please provide any suggestions or any sample code for it.
Thanks in advance.
try this in your appDelegate didFinishLaunchingWithOptions method
MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:#"MasterViewController_iPad" bundle:nil] autorelease];
UINavigationController *masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
DetailViewController *detailViewController = [[[DetailViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil] autorelease];
UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
self.splitViewController = [[[UISplitViewController alloc] init] autorelease];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationControlle, detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
This is certainly possible. There are no limitations on what you can display in the master and detail views of a split view controller.
Think of the split view as merely a view that displays two of your view controllers. They can contain anything.
If I understood what you're trying to achieve correctly then what you want to do is create a View Controller with a UITableView which will display the data in the left column. This View Controller should also have a UINavigationController which will push another view controller when you select something in the table.
So far, so good. Nothing has changed in the detail view since it in reality isn't aware of or connected to the master view in any way. When the user has moved enough steps down in the master view, and you want to change the detail view - then you can set the viewControllers-property of the navigation controller to update the detail view with whichever view controller you want to display.
Yes you can. Apple has provided a sample code called MultipleDetailViews
It shows how communication is done between master and detail using delegation.
See these Tutorials :-
http://www.icodeblog.com/2010/04/05/ipad-programming-tutorial-hello-world/
http://www.raywenderlich.com/1040/ipad-for-iphone-developers-101-uisplitview-tutorial
These will help you.

Setting root view controller in didReceiveLocalNotification: results in black window

I know different versions of this question has been asked before but I'm really stuck here. I'm trying to get my app to push a new view from my app delegate when getting:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)localNotif {
And I put the following code in there:
MyViewController *myViewController = [[MyViewController alloc]init];
nvcontrol = [[UINavigationController alloc] initWithRootViewController:myViewController];
[nvcontrol.navigationBar setTintColor:[UIColor blackColor]];
self.window.rootViewController = nvcontrol;
and from this, I get a black view (which myViewController should not have) with a black navigation bar.
What am I doing wrong here?
As I've outlined above, you can use storyboard to set the initial view controller.
Note that if you have a view controller set up in storyboard and then you create a view controller in the application delegate, the view controller you created won't look like your one in storyboard. This is because you are making an instance of the CLASS, but the program has no way to associate this with your layout.

TabBarController inside NavigationController

Imagine that we have multiview apllication which is controlled by Navigation Controller. We go from the first view to second by using pushViewController method and that's not a problem but then we need to move to the third view. And the third one is a view which looks like a TabBar. How do we do that? The third view is supposed to be controlled by TabBarController, isn't it?
So how to pass the control? I declared an outlet UITabBarController * tbc and connected it to TabBarController in xib file and then i tried this in viewDidLoad:
tbc = [[UITabBarController alloc]init];
and it shows nothing.
Your help is highly appreciated
It's a bit wierd. Its more standard to have a tabBarController that switches views and some of those views may be navigation controllers. But ...
Create the UITabBarController and push it.
NSMutableArray *viewControllers = [[NSMutableArray alloc] init];
// create someView
[viewControllers addObject:someView];
// create someView2
[viewControllers addObject:someView2];
UITabBarController *tabController = [[UITabBarController alloc] init];
[tabController setViewControllers:viewControllers];
[[self navigationController] pushViewController:tabController animated:YES];
Then, from the tabBarContoller view, based on some action, you can choose to pop it:
[self.navigationController popViewControllerAnimated: NO];
You can wire it up in the storyboard editor in the latest version of Xcode.
However, since this is very much non-standard use of the controls, you would need a very good reason as to why you would want a UI like this.
And even then, Apple's review process might turn your app down if the interface is clunky.

How to switch page on UINavigationBar on iPhone

I want to ask a question about the UI item on the UINavigationBar on the iPhone application. Im my program, there are a navigation bar and UITableView, like the following structure.
UIView (DataRootViewController.m)
|
+- UINavigationBar
|
+- UITableView
And, I want the it display the detail of the data when the user press one of the cell on the UITableView.
However, I don't know what should I do. I just create a class with UIViewController type (called DataDetailViewController.m) and leave it empty. What should I do for the next step? Which UI element should I add on the navigation bar in the detail view in order to let the user to go back to the basic page.
thank you very much.
You should be using a UINavigationController instead of trying to replicate the behavior. On your app delegate, try something like this.
RootViewController *rootViewController = [[RootViewController alloc] init];
UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[window addSubview:[self.tabBarController view]];
Now, this RootViewController should have a table view, and when a user taps the table you should build your detail view controller and use
[[self.navigationController] pushViewController:myDetailViewController animated:(BOOL)animated];