Presenting Modal View Controller before window is visible - iphone

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.

Related

View is not displaying after pushing on navigationController stack

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!

Show View Controller Modally on First Startup

I'd like to have a view with instructions on how to use my app show up on the first time the app is opened. I have handled the problem of the only showing this view on the first startup using NSUserDefaults, but I am having trouble getting the view to display the way I want it to modally, not as the rootViewController. Here is my AppDelegate.m code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
BOOL hasShownStartup = [[NSUserDefaults standardUserDefaults] boolForKey:kAppHasShownStartupScreen];
if (!hasShownStartup) {
[self showInstructions];
}
[self.window makeKeyAndVisible];
return YES;
}
- (void)showInstructions
{
NSLog(#"showing instructions");
InstructionsViewController *howToView = [[InstructionsViewController alloc] initWithNibName:#"InstructionsViewController"
bundle:nil];
self.instructionsViewController = howToView;
[howToView release];
UINavigationController *howtoNavController = [[UINavigationController alloc]
initWithRootViewController:self.instructionsViewController];
self.instructionsViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.viewController presentModalViewController:howtoNavController animated:NO];
[howtoNavController release];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAppHasShownStartupScreen];
}
I want my rootViewController to remain self.viewController. I want to be able to click 'Done' on the instructionsViewController nav bar to transition back to the rootViewController. Executing the code as written never shows the instructions view. The only way I can see instructionsViewController is if I change the line [self.viewController presentModalViewController:howtoNavController animated:NO]; to self.window.rootViewController = self.instructionsViewController; but this is obviously not what i want (unless I could modally transition back to viewController).
Hopefully I've made it clear enough what I am trying to accomplish. Thanks in advance.
Try moving [self showInstructions]; to applicationDidBecomeActive: instead.
Try putting the [self showInstructions] after [self.window makeKeyAndVisible]:
[self.window makeKeyAndVisible];
if (!hasShownStartup) {
[self showInstructions];
}

What can I do if my navigationController returns "(null)"? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can't I push a new view controller onto the current view?
Why is my new view controller not appearing?
I need to push my view controller from my navigationController, but after having done an NSLog statement to find out why nothing was showing with the following code, I realised that it was returning null:
-(IBAction)doChangePasscode{
NSLog(#"Change Passcode Screen Loaded!");
ChangePasscode *cpscreen = [[ChangePasscode alloc] initWithNibName:#"ChangePasscode" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:cpscreen animated:YES];
NSLog(#"%#",self.navigationController);
}
Why is this happening? What can I do to return a proper value other than (null)?
Like everyone has explained in this and Why is my new view controller not appearing?, you need to have a navigation controller first. Use that nav controller to push your view controllers and then your view controllers will no longer have null for the navigationController property.
In this example someSecondViewController would be the self in your code above:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
self.nav = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];
[rootViewController release];
[self.window addSubview:nav.view];
[self.window makeKeyAndVisible];
}
- (void)someOtherMethod {
SecondViewController *someSecondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.nav pushViewController:someSecondViewController animated:YES];
[someSecondViewController release];
}
Please review these:
View Controller Programming Guide for iOS
UINavigationController Docs
UIViewController Docs
I am assuming you mean returning nil, that means the viewController does not have a navigation controller, you can solve it by having your viewController be the root of a newly created UINavigationController like this:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myRootViewController];
Then for myRootViewController self.navigationController will return the navigation Controller.
I am assuming that viewController is the first one in your app so you want to have this on your appDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MyViewController *viewController = [[[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil] autorelease];
UINavigationController *myNavController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
self.window.rootViewController = myNavController;
[self.window makeKeyAndVisible];
return YES;
}
Then if that IBAction is on MyViewController self.navigationController will return the navigation Controller instead of nil.
Hope that helps.

How to show UINavigationController on view

- (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];

Adding UINavigationController to existing UIViewController

How do I add an existing UIViewController (which is presented using presentModalViewController) to a UINavigationController?
When user tap on button, a new copy of my detail view need to be pushed. (In other words, pushViewController displaying pushViewController, modally, in a UINavigationController).
Easiest way to enable this functionality?
how do you create your modal viewcontroller? Just wrap the controller into a UINavigationController
Let's assume your modal code is like this:
MyExampleViewController *vc = [[[MyExampleViewController alloc] initWithNibName:#"MyExample" bundle:nil] autorelease];
[self presentModalViewController:vc animated:YES];
Then change it into something like this:
MyExampleViewController *vc = [[[MyExampleViewController alloc] initWithNibName:#"MyExample" bundle:nil] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
[self presentModalViewController:navController animated:YES];
I think you need to add a navigation controller in your delegate, after that you can push the view. So that you can push the view from anywhere in your application.
on AppDelegate.h
UINavigationController *navig;
on AppDelegate.M
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
navig = [[UINavigationController alloc] initwithRootViewController:viewController.view];
//[navig pushViewController:viewController animated:YES];
[self.window addSubview:navig.view];
[self.window makeKeyAndVisible];
return YES;
}