I'm trying to get the slide animation that occurs with a UINavigationController.
All of the UINavigationController setup examples involve using multiple XIB's for different views, however all my views are UIViewControllers in one XIB.
So far, I'm using [self presentModalViewController:myViewController animated:YES];, which works perfectly fine.
All of my view controllers are connected through IBOutlets to the main XIB.
Example :
#import "MyViewController.h"
#interface ViewController : UIViewController {
...
IBOutlet MyViewController *myViewController;
//connected through Interface Builder
...
}
And in Interface Builder:
I thought I could use something like:
UINavigationController *myNavController = [[[UINavigationController alloc] initWithRootViewController:self] autorelease];
[myNavController pushViewController:myViewController animated:YES];
However that does absolutely nothing.
I'm a bit stuck on this.
Any help appreciated.
You have to add the view of the UINavigationController to your view hierarchy at some place.
In the Xcode template Navigation-based Application this done by adding it to the UIWindow:
[window addSubview:navigationController.view];
I've cracked it after looking at Apple's UINavigationController documentation.
I created a UINavigationController in my Application's didFinishLaunchingWithOptions: method like so:
UIViewController *dcview = [[DocumentationViewController alloc] init];
navigationController = [[UINavigationController alloc]
initWithRootViewController:dcview];
[dcview release];
navigationController.navigationBarHidden = YES;
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
and then calling
[((DocumentationAppDelegate *)[UIApplication sharedApplication].delegate).navigationController pushViewController:settingsView animated:YES];
to push it.
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];
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 have my app like this : a navigationBar in the app delegate with have a Controller1(UIViewController) like a rootController, in the controller1 i push controller2 ( UIViewController), the controller2 have 3 UINavigationController, and a Custom tabBar, each navigationController have a root controller, and finally i put all the navigationController in the CustomTabBar.
My question is : is this clean( good) to do like this ? If no how i can organize my project ?
MyAppDelegate.h
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *navigationController;
#property (strong, nonatomic) CustomTabBar *tabBarController;
MyAppDelegate.m {
UIViewController *controller1 = [[UIViewController alloc] initWithNibName:nil bundle:nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
navigationController = [[UINavigationController alloc] initWithRootViewController:controller1];
self.window.rootViewController = navigationController;
}
controller1.h
UIViewController controller2;
UINavigationController *navigationController2;
UIViewController controller3;
UINavigationController *navigationController3;
UIViewController controller3;
UINavigationController *navigationController3;
controller1.m
-(void)viewDidLoad{
viewController1 = [[UIViewController......
navigationController1 = [[UINavigationController alloc] initWithRootViewController:controller1];
....
AppDelegate *apDelegate= [UIApplication sharedApplication].delegate;
apDelegate.tabBarController = [[CustomTabBar alloc] initWithNibName:nil bundle:nil];
[apDelegate.tabBarController setViewControllers: [NSArray arrayWithObjects:navigationController1,navigationController2,navigationController3,nil]];
}
This is an excerpt from the apple documentation:
When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller.
From my point of view it's a bit tricky from the start to sort out how to use UITabBarController class, so in this case the better approach is to see some good manual. For me this one helps always when I start to mess around with this UI thing :)
Good luck.
EDIT:
In order to have your tabbar appear only in some concrete views, you have to hide your tabbar from the start of the app, and make it appear only when you really need it.
In order to hide it, you can use the method:
[theTabBar setHidden:YES];
Set the tabBarController as rootViewController of window object:
self.window.rootViewController = tabBarController;
Or you can set tabBarController.view as subview of window object:
[self.window addSubView:tabBarController.view];
if you want add the tabBarController to the secondo view:
[secondViewController.view addSubView:tabBarController.view];
or, for the navigationController
[navigationController1.view addSubView:tabBarController.view];
or
navigationController1.rootViewController = tabBarController;
In other words in the controller1.m you declare a TabBarController and add navController1, navController2 etc.
Then add the tabBarController to controller1 as rootViewController or as subView.
I hope this is what you were looking!
I wanted to add a navigation controller to a view based application . how can we do this both programmatically and using xib file..
If you need to incorporate a navigation controller in your uiviewcontroller you need to initialize it as it follows
UIViewController *yourViewController = ...
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:yourViewController];
[self presentModalViewController:navController animated:YES];
//you need to release the controller
[navController release];
If you are in the UIApplicationDelegate method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
You can't do a presentModalViewController:navController animated... then you need to add the navController.view to the window
UIViewController *yourViewController = ...
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:yourViewController];
[self.window addSubview:navController.view];
//don't do a release of navController because is not retained by addSubview
UINavigationController *navcontroller = [[UINavigationController alloc] initWithRootViewController:viewController];//here viewController is to which you want to make the navigation
[self.view addSubView:navController.view];
You can just drag a "Navigation Bar" from your objects in the bottom right corner of Interface Builder. This basically does what Sachin says in his answer but you still have to programmatically create the functionality of the navigation controller. I.e pushing new views to the stack and poping them off.
In my opinion it's easiest to do it entierly in the code.
If you want to have a navigation controller as the root view for your main window. Then you can do so by using the following code.
#interface yourAppDelegate_iPad : NSObject <UIApplicationDelegate> {
UINavigationController *navigationController;
}
#property (nonatomic, retain) UINavigationController *navigationController;
#end
#implementation yourAppDelegate
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
navigationController = [[UINavigationController alloc] initWithRootViewController:yourRootViewController];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
You can do this by using the xib as follows
Open the MainWindow.xib
Drag and drop a UINavigationController to it.
Create and connect the outlets.
Open attributes for the navigation controller and set the root
view.
I am having a problem with the following code:
MyViewController *aController = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
self.myController = aController;
myController.title = #"List";
[aController release];
UINavigationController *bController = [[UINavigationController alloc] initWithRootViewController:myController];
self.rootNavController = bController;
[bController release];
[self.view addSubview:rootNavController.view];
When I run my program I get the problem where my view for myController is repeated along the y-axis all the way until the bottom of the screen. If I add myController.view to the root view it works ok. I only have the problem when I add myController as the rootViewController of my navigation controller.
Thanks in advance for any help!
The default navigation controller project template defines -applicationDidFinishLaunching this way:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
I realize you're instantiating your nav controller with alloc init rather than getting it from the XIB, however, it seems you ought to be adding it to the window's view tree.
Where is the code you are showing being called from?
The problem was that I did not specify the frame. Without specifying a frame using CGRectMake the view controller was just filling the entire space.
The line I needed was something like this:
rootNavController.view.frame = CGRectMake(0, 0, 320, 431);
Try this:
MyViewController *aController = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
self.myController = aController;
[aController release];
UINavigationController *bController = [[UINavigationController alloc] initWithRootViewController:myController];
self.rootNavController = bController;
[bController release];
[window addSubview:rootNavController.view];//<--What are you adding the navigationController to??? Another ViewController? TabController? or Window?
Then in the -(void)viewDidLoad method of MyViewController you can put
self.navigationItem.title = #"List";