I am wondering, that how to get navController from AppDelegate = [[UIApplication sharedApplication] delegate] in the iPhone programming. e.g., in other viewController where we reference to the AppDelegate.
In the applicationDelegate.h we have:
UINavigationController *navController;
And the following in applicationDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview: navController.view];
[window makeKeyAndVisible];
}
Is there anyway to get the navController from the mainWindow:
UIWindow *mainWindow = [appDelegate window];
If this other UIViewController is contained in the UINavigationController, you can simply call:
UINavigationController *navController = self.navigationController;
from the UIViewController.
Otherwise, you can set UINavigationController as a property in the AppDelegate.
// AppDelegate.h
#property (nonatomic, strong) UINavigationController *navController;
Then access appDelegate.navController.
Or, you can set the UINavigationController as window's rootViewController:
[window setRootViewController:navController];
And call from anywhere:
UINavigationController *navController = window.rootViewController;
You can make the navController a property
#property (nonatomic,strong) UINavigationController *navController;
Then just access it from your appdelegate
appDelegate.Controller
You can make the navController as a property of your delegate class. sample below:
In applicationDelegate.h
#property (retain, nonatomic) UINavigationController *navController;
In applicationDelegate.m
#synthesize navController;
then you can use the following code to get the navController in other classes (Assume your delegate class is MyApplicationDelegate):
appDelegate = (MyApplicationDelegate*)[[UIApplication sharedApplication] delegate];
UINavigationController *navController = appDeleagte.navController
No extra properties needed, available almost anywhere in your application using this macro definition:
#define mainNavController (((AppDelegate*)[[UIApplication sharedApplication] delegate]).navController)
When you put the macro at the top of your source or in a .h header file that you import into your source, then you can start using mainNavController as if it were a local variable.
For example:
[mainNavController pushViewController:myViewController animated:YES];
Or without the macro, directly in code:
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
appDelegate.navController; // do something with the navController
You can use this code almost anywhere, which is handy if you're working inside a class and you can't access a ViewController directly.
If you are beginer and learner, the navigation controller is shared in whole application which will just prepare the "stack" of your app's viewcontrollers, so you can access the navigationcontroller in any viewcontroller(Only if that controller has been pushed) through out the app. When you push any controller it will added to the "stack" of navigation controller.
You can access the navigation controller with the self object of that viewcontroller itself.
[self.navigationController pushViewController:detail animated:YES];
Go through with the link will give complete knowledge of navigation anatomy.
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html
Related
I have a storyboard based Single View App;
I have 3 ViewControllers on my Storyboard linked to 3 ViewController classes in the code;
I browse between ViewControllers by doing this:
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
MenuViewController* mainMenu = [sb instantiateViewControllerWithIdentifier:#"vcMainMenu"];
mainMenu.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:mainMenu animated:YES];
Now I need to access different UIcontrols on the applicationWillResignActive from the current active ViewController, I will access different controls depending of the ViewController, I'm trying to accomplish this by doing:
if ([self.window.rootViewController isKindOfClass:[LowProfileViewController class]])
{
NSLog(#"here!");
}
But it always returns the rootViewController. How Can I get the current displayed rootViewController from applicationWillResignActive?
Please, Incorporate NavigationController is not an option...
thanks
You could try this -
Make An AppDelegate #property (i.e. currentModelViewController)
#property (nonatomic, retain) UIViewController *currentModelViewController;
For each ViewControllers in viewDidAppear or in viewWillAppear
appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.currentModelViewController = self;
Now this will work
if ([self.currentModelViewController isKindOfClass:[LowProfileViewController class]])
{
NSLog(#"here!");
}
I first like to load simple viewController which shows some option and then clicking on some button I would like to load navigationController or tabbarController depending on button click. How can I do this ?
I replace the root view controller on the window when I want to switch the views.
For example in my app I show a loading screen first then I switch the view to a login screen.
To do this you need a reference to your app delegate then you can access the window property and replace the root view controller:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
LoginViewController *loginVC = [[LoginViewController alloc] init];
appDelegate.window.rootViewController = loginVC;
In your simpleViewController :
- (IBAction) yourButtonAction:(id)sender
{
UIViewController *Vc = [[theViewControllerYouWantToShow alloc]init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:Vc];
[self presentModalViewController:nav animated:YES];
}
Edit :
you have three options to show your viewController content :
as the example above using presentModalViewController:
add the viewController view as a subView to the current viewController.
in your case : [simpleViewController.view addSubView:nav.view];
3.or if your simple ViewController is the navigation root viewController you can push other viewControllers to its navigation stack.
in appdelegate.h
#property (strong, nonatomic) id<UIApplicationDelegate>delegate;
in appdelgate.m
#synthesize delegate;
in my first viewController's .h file
AppDelegate *myappDelegate;
-(IBAction)start:(id)sender;
in my first viewController's .m file
-(IBAction)start:(id)sender
{
NSLog(#"Start Button is clicked");
mvc = [[MasterViewController alloc]initWithNibName:#"MasterViewController" bundle:nil];
myappDelegate = [[UIApplication sharedApplication]delegate];
myappDelegate.navigationController = [[UINavigationController alloc]initWithRootViewController:mvc];
myappDelegate.window.rootViewController = myappDelegate.navigationController;
[myappDelegate.window makeKeyAndVisible];
}
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 have a root view controller which should load another view controller as soon as it is done loading (i.e. in the viewDidLoad method).
I am using the UINavigationController in order to push a new view controller onto the stack:
In my rootviewcontrollerappdelegate:
-(void) viewDidLoad{
LoginViewController* lvc = [[LoginViewController alloc]init];
[self.navigationController pushViewController:lvc animated:NO];
}
I have textfields and buttons in the view controller to be loaded. The above doesn't seem to work however...It loads just a blank grey screen and no UINavigation bar is present. If I comment out the second line (pushViewController line), then I see the navigation bar. So I think it is loading something, but the items in the view controller being loaded are not being shown...Any ideas why?
Check if navigationController is pointing to nil. If it does, try
[self.view addSubview:self.pushViewController.view]
I had the same problem and found the above solution here:
UIViewController -viewDidLoad not being called
Unless you're doing something tricky, you should be calling alloc on the LoginViewController class rather than a variable. Also, if you've set up LoginViewController in Interface Builder (as opposed to programmatically), you'll need to load it from an NIB:
LoginViewController *lvc = [[[LoginViewController alloc] initWithNibName:nil bundle:nil] autorelease];
[self.navigationController pushViewController:lvc animated:NO];
Have a look at initWithNibName:bundle: in the docs.
Not entirely sure what you are trying to achieve but when you instantiate LoginViewContoller it should probably look like this
LoginViewController* lvc = [[LoginViewController alloc]init];
Judging by the nature of your naming for your view controller, is your LoginViewController the first view controller for your UINavigationController?
If that is what you're trying to do, you should instead initialise your navigation controller with the LoginViewController as the root controller instead of pushing it onto the navigation stack.
UINavigationController has a method to do this:
- (id)initWithRootViewController:(UIViewController *)rootViewController
EDIT:
Well, one way you can go about it is like this.
In your application delegate .h file, you should have declared a UINavigationController.
#interface MyAppDelegate : NSObject <UIApplicationDelegate>
{
UINavigationController *navController;
}
#property (nonatomic, retain) UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
In your App Delegate didFinishLaunching:withOption: you can create an instance of your LoginViewController there, and use that to init your UINavigation controller as the root view controller
#import "LoginViewController.h"
#implementation MyAppDelegate
#synthesize navController;
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LoginViewController *loginController = [[LoginViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:loginController];
[loginController release];
[[self window] setRootViewController:navController];
[navController release];
[self.window makeKeyAndVisible];
return YES;
}
I probably have a typo here or there but that's one way I would go about doing it.