I am trying to use a navigation controller to push/pop views, but I don't want the bar at the top with the buttons; I'm doing the navigation UI myself.
So I created a navigationController in my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[WSViewController alloc] initWithNibName:#"WSViewController" bundle:nil];
self.window.rootViewController = self.viewController;
self.navController = [[UINavigationController alloc]
initWithRootViewController: self.viewController];
[self.window makeKeyAndVisible];
return YES;
}
and then in my WSViewController, I have an IBAction method that pushes another view on the navigation stack (I've verified that it's doing this correctly; I see it on the stack):
- (IBAction)showInfo:(UIButton *)sender {
if (self.wsInfoViewController == nil) {
WSInfoViewController *wic = [[WSInfoViewController alloc] initWithNibName:#"WSInfoViewController" bundle:nil];
self.wsInfoViewController = wic;
}
[self.navigationController pushViewController:self.wsInfoViewController animated:YES];
}
But I'm not seeing the info view show up when I tap on the info button in my WSViewController (which is showing up just fine).
If I make the navigationController the root controller, then I do see the wsInfoViewController when I tap on the info button, however, I also get the navigation bar at the top, which I don't want!
So... first, am I wrong in thinking I can use a navigation controller this way (i.e. using it for stack purposes but not for any UI at all)?
Second, if I'm not wrong, why isn't the view I'm pushing onto the stack showing up? I'm guessing it's because I'm not hooking the navigation controller up to the window correctly, but I'm not sure how to do that.
Thanks!!!
Elisabeth
So I think I have the answer to my question. Which is, you must set up the navigation controller as the root view controller for the AppDelegate window in order to use it, otherwise, the window doesn't know about it. My WSViewController is still the root view controller for the navigation controller. And then to get rid of the navigation bar, you can hide it.
Here's the updated code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[WSViewController alloc] initWithNibName:#"WSViewController" bundle:nil];
// doesn't work!
//self.window.rootViewController = self.viewController;
self.navController = [[UINavigationController alloc]
initWithRootViewController: self.viewController];
// do this instead
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
return YES;
}
To hide the nav bar in the views, in each view where you want it hidden, add the following methods:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
This is working great so far!
Related
I'm using xCode 4.3.2 and started a blank application.
I have a navigation controller and a simple logincontroller. I want the login controller to be my root view so it is this first thing that a user does when they login.
I'm using the following code and when I run the application it displays a black screen. I put in logging in the LoginViewController.m->ViewDidLoad and it is being run is there something im doing wrong the LoginViewController.xib is very simple it just contains a button right now that will switch to a tab view controller once I figure this out.
Thanks in advance.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
UIViewController *loginController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:loginController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:navigationController.view];
[self.window makeKeyWindow];
return YES;
}
This is not right:
[self.window addSubview:navigationController.view];
change it to this:
self.window.rootViewController = navigationController;
I'm having trouble coding a button to go to the previous page. I was able to do it to go to the next page thinking if I did the same thing but changed it a bit it would work in reverse. Unfortunately, I come up with a lot of errors I can't resolve because it won't allow me to use the release function.
This is this the code that helps it to work going to the next page fine:
#import "ViewController.h"
#implementation ViewController
-(IBAction)btnClicked:(id) sender
{
//add the view of the view controller to the current View---
if (menuView==nil) {
menuView =
[[MenuView alloc] initWithNibName:#"MenuView"
bundle:nil];
}
[self.view addSubview:menuView.view];
}
-(void)dealloc {
[menuView release];
[super dealloc];
}
How do I do it so that a back button will go to the previous page though.
It's pretty simple, use this :
-(IBAction)back:(id) sender
{
[menuView.view removeFromSuperview];
}
But, I would suggest not using addSubview: for many views as it would be complex way to do. Use UINavigationController as #Paul.s suggested.
The way you are doing this is not quite correct and I would suggest doing some reading to get familiar with iOS programming.
Your program structure should be: create a navigation controller (2) to manage the stack of view controllers giving it a viewController (1) to act as it's root.
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// 1
FirstViewController *firstViewController = [[FirstViewController alloc] init];
// 2
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[firstViewController release]; firstViewController = nil;
self.window.rootViewController = navigationController;
[navigationController release]; navigationController = nil;
[self.window makeKeyAndVisible];
return YES;
}
This will display your first view controller inside a UINavigationController. A UINavigationController is responsible for managing a stack of UIViewController's and giving you UI to navigate back down the stack as well as calling all the appropriate presentation related methods on a UIViewController at the correct times e.g. viewDidLoad. You should check out The View Controller Programming Guide for lots of info
Then inside your first view controller you do something like this to respond to the button:
- (IBAction)buttonClicked:(id)sender;
{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release]; secondViewController = nil;
}
This creates a new view controller and pushes it onto the stack.
I would like to present a view controller modally before calling -makeKeyAndVisible on the application's window. However, this code only shows the mainNav view controller:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MainViewController *main = [[MainViewController alloc] init];
UINavigationController *mainNav = [[UINavigationController alloc] initWithRootViewController:main];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Restore"])
{
DetailViewController *detail = [[DetailViewController alloc] init];
UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:detail];
// changing main to mainNav does not help
[main presentModalViewController:learnNav animated:NO];
[detailNav release]; [detail release];
}
self.window.rootViewController = mainNav;
[main release]; [mainNav release];
[self.window makeKeyAndVisible];
return YES;
}
What am I missing?
You should better make the window appear and then present the modal view with animated=NO. What's the point of presenting the modal view before everything else is instantiated and displayed?
Edit
To try to make your code work, here are a couple of hints. Try this:
[mainNav presentModalViewController:learnNav animated:NO];
or this:
[main.navigationController presentModalViewController:learnNav animated:NO];
I'd say that these two methods work best if they're put after the makeKeyAndVisible call.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
UINavigationController *nav_obj = [[UINavigationController alloc] initWithRootViewController:overviewViewController ];
[self.viewController presentModalViewController:nav_obj animated:YES];
[overviewViewController release];
[self.window makeKeyAndVisible];
return YES;
}
This code shows the blue bar of navigation controller, but no buttons on it.It seems like to be that the UINavigationController allocated as empty.
Who knows what problems is?
UPD:Archive http://www.mediafire.com/?lbjjvl6fcue2q18
Please help me, I'm new in objective-c
You need to create the button for it, for example:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:launcherView action:#selector(endEditing)];
self.navigationItem.leftBarButtonItem = doneButton;
[doneButton release];
The correct way to use a UINavigationController is to push view controllers on to it. That way they will be stacked and the navigation bar will be populated with a back button when it is case (i.e., when you can actually go back to a previous controller). You control the label that appears in the "back" button by defining the title of the controllers you push.
The technique shown in another answer (setting explicitly the button) is useful with defining the right button, if you ever need one.
You could try with this code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
UINavigationController* navigation = [[UINavigationController alloc] init];
[navigation pushViewController:overviewViewController animated:NO];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
Instead of doing:
UINavigationController* navigation = [[UINavigationController alloc] init];
[navigation pushViewController:overviewViewController animated:NO];
you could also use initWithRootController, but to display the general case of how you push a view controller I preferred this one.
Notice that since you are pushing just a root controller, you should see no back button at the moment, but if you push a second view controller, then it will appear.
EDIT: I gave a look at your project. Summary of what you should try and do:
objects you need in your NIB: File's Owner (UIApplication), First Responder, FBFun App Delegate (iVkAppDelegate), Window (UIWindow); remove the rest;
File's owner delegate outlet is FBFun App Delegate;
FBFun App Delegate window outlet is Window.
With this simple setup (more or less what you have), use this code :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UINavigationController* navigation = [[UINavigationController alloc] init];
//-- MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
iVkViewController *overviewViewController = [[iVkViewController alloc] init];
overviewViewController.title = #"First";
[navigation pushViewController:overviewViewController animated:NO];
iVkViewController *overviewViewController2 = [[iVkViewController alloc] init];
overviewViewController2.title = #"Second";
[navigation pushViewController:overviewViewController2 animated:NO];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
In the code above, as you notice, I instantiated twice your iVkViewController just to have a second controller to push onto the navigator.
Please, delete your existing app from the simulator, and the run this in order to see that the navigation bar is correctly created and you can go back from the second controller to the first one.
I removed usage of MainPageDialog, because the MainPage nib has many problems.
But I hope this skeleton is sufficient for you to go forward with your development.
You had missed the line as you are not adding view to window.Add this line in your code
[window addSubview:nav_obj.view];
my first xib contains a ScrollView with a springboard like interface in MainWindow.xib:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
navController = [[UINavigationController alloc] init];
[navController setNavigationBarHidden:YES];
[window addSubview:navController.view];
[window sendSubviewToBack:navController.view]; }
When a button is clicked the FirstViewController appears with a tableview and a navigation controller:
- (void) buttonPushed:(id)sender {
FirstViewController *firstViewController = [[FirstViewController alloc] init];
[navController pushViewController:firstViewController animated:YES];
[firstViewController release];
[window addSubview:navController.view]; }
When I click the back button in Navigation Controller to go back to springboard, I get the springboard xib, but unresponsive to touches with a Navigation Bar on top!
- (void)goHome:(id) sender {
[self.view removeFromSuperview];
How can I go back to springboard screen (mainwindow.xib) without having the navigation bar stacked on top, and be responsive to touches ?
Why don't you set the springboard view to be the root view controller of your navigation controller and get rid of any UI in the window?
I think that the window shouldn't have any UI elements accept view of view controllers that are added to it (by navigation controller or by tab bar controller).
This way you won't have to reinvent the wheel for the first view to load from the springboard view and the back button will work properly.
You can set the navigationBarHidden property to false in the viewDidLoad method of the root view controller (the view controller of the springboard view).
Did you try calling [navController setNavigationBarHidden:YES]; in your mainview viewWillAppear callback ?
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
UIViewController *rootController = [[MyRootViewController alloc] init];
navigationController = [[UINavigationController alloc]
initWithRootViewController:rootController];
[rootController release];
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
}