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;
}
Related
I've tried every solution on Google and nothing seems to work. So far I've implemented a UINavigationController with the App Delegate, now all I want to accomplish is changing to the WebViewController by clicking the UIButton I've created in the interface builder, but the button doesn't seem to do anything when I run the application. Keep in mind that I want it to push to my WebViewController view.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
ViewController.m
- (IBAction)createFile:(id)sender {
WebViewController *webViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:NSBundle.mainBundle];
[self.navigationController pushViewController:webViewController animated:YES];
}
Note: In the interface builder I've already connected createFile to the button.
I understand that this is usually something that comes known as super easy but for some reason I've just never gotten it to work. Thanks in advance.
EDIT: I added the retaining property, sythesized it and added to my code in the ViewController.m file:
WebViewController *webViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:NSBundle.mainBundle];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:webViewController];
[self.navigationController pushViewController:webViewController animated:YES];
But now the app crashes on the button click and returns with a SIGABRT: "Pushing the same view controller instance more than once is not supported (WebViewController: 0x1ed70e80)"
give this a try
-(IBAction)createFile:(id)sender{
WebViewController *webViewController = [[WebViewController alloc]
initWithNibName:#"WebViewController" bundle:nil];
webViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:webViewController animated:YES];
}
One thing i noticed is that you are not retaining your navigationController in the appDelegate. So what may be happening is that your the navigationControllers view may be present and retained (from the all to addSubView) but the navigation controller may have been deallocated.
in your AppDelegate try making the Navigation Controller a retaining property
#property (nonatomic, strong) UINavigationController *navigationController
in your .m file
#synthesize navigationController
and then
Edit: Updated for pushing a view controller
WebViewController *webViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:NSBundle.mainBundle];
[self.navigationController pushViewController:webViewController animated:YES];
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.
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];
I am working with push notifications. i am trying to create and push a DetailView in the navigationController when action button in notification is clicked. but navigationController is nil. how can i put that DetailView in the navigationController? I want to push RootViewController in the navigationController and then the DetailView. how can i do that?
in AppDelegate:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
RootViewController *controller = [[RootViewController alloc] init];
//getting warnings here.(Unused variable navigationController)
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[controller doStuff];
[controller release];
}
in RootViewController:
-(void)doStuff{
[[self stories] removeAllObjects];
[self startParsing];
[self.tableView reloadData];
DetailViewController *detail = [[DetailViewController alloc] init];
//custom code
[self.navigationController pushViewController:detail animated:YES];
[detail release];
this is the code i m using right now. and plz notice that i have
[self.tableView reloadData];
Okay, now I am pretty sure I understand the issue. The problem is, you never manually set the navigationController property on a UIViewController. The navigationController property is nil if the view controller is not under a navigation controller and if it is, then the property points to it.
What you need to do, is when you display your root view controller, instead of directly displaying its view, add it to a navigation controller, then display the navigation controller's view. Like so:
RootViewController *controller = [[RootViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
//Here you would display navigationController.view somehow
So, after you have your root view controller in a navigation controller, in a method in root view controller you can do this:
DetailViewController *detail = [[DetailViewController alloc] init];
//Do whatever you need to do to set values on the detail view controller
[self.navigationController pushViewController:detail animated:YES];
The key thing is this: you need to put the root view controller into a navigation controller before you can access a navigation controller from within root view controller.
If your nav controller is nil, it needs creating and then you place things into it.
Try this:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[navController pushViewController:detailViewController animated:NO]; // or YES
If you start out with no UINavigationController and want to display it with more than one view controller in its stack, after initing the navigation controller you can set the viewControllers property to an array with the various view controllers you want.
edit: some example code:
UINavigationController *navController = [[UINavigationController alloc] init];
NSArray *viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
[navController setViewControllers:viewControllers animated:NO];
After doing that, your navigation controller will have viewController2 on top and viewController1 behind it.
Alternately, you could do it this way:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController1];
[navController pushViewController:viewController2 animated:NO];