How to properly set up UINavigationController and add views to the stack - ios

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self. window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
UINavigationController *navVC = [UINavigationController new];
UIStoryboard *mStoryboard = [UIStoryboard storyboardWithName:#"your storyboard name" bundle:nil];
ViewController *VC1 = [mStoryboard instantiateViewControllerWithIdentifier:#"VC"];
[navVC setViewControllers:[NSArray arrayWithObject:VC1] animated:NO];
[self. window setRootViewController:navVC];
[self. window makeKeyAndVisible];
return YES;
}
Now this creates a navigationController but when i try to display the secondViewController it does display me the correct Navigation Bar for that view but i see a black background instead of the actual view. Adding secondViewController as a subview works but when i now try to display the third one it does again display me the correct navigation bar with the set title for this view but i still see the secondViewController's view. Now my question how do I add viewController to the navigationController so they are displayed right? do i even have to add them? I've read through the apple class reference but there isn't any code.

try this:
self. window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
UIStoryboard *mStoryboard = [UIStoryboard storyboardWithName:#"your storyboard name" bundle:nil];
ViewController *VC1 = [mStoryboard instantiateViewControllerWithIdentifier:#"VC"];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:VC1];
[self. window setRootViewController:navVC];
[self. window makeKeyAndVisible];
return YES;
now inside VC1 push the next view controller to your stack with
// EDIT:
UIStoryboard *mStoryboard = [UIStoryboard storyboardWithName:#"your storyboard name" bundle:nil];
ViewController *vC2 = [mStoryboard instantiateViewControllerWithIdentifier:#"VC2"];
[self.navigationController pushViewController:vC2 animated:YES];

Related

Initializing a view controller as a initial view controller while using navigational controller ?[Objective-C]

I have tried using navigation view controller and setting up my screen as initial view controller using storyboard and it went well.
But when I did everything programmatically like below in my appDelegate.m file :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName: #"Main" bundle:nil];
FirstViewController *firstVC = [storyboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: firstVC];
self.window =[[[UIApplication sharedApplication]delegate] window];
self.window.rootViewController = navController;
return YES;
}
My screen on the simulator is blank.
But when I checked the is initial view controller for the respective view controller in the storyboard and run. This time, it worked, and the expected screen is displayed.
My question is, why should I check the is initial view controller in the storyboard when I am doing everything programmatically ?.
Thank you.
If you're going to create the first view controller yourself in didFinishLaunchingWithOptions, you have to instantiate the UIWindow, too. But your assignment of self.window is just retrieving itself (lol) and does nothing. You'd generally do something like:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
When you use the "initial view controller" option, it takes care of all of this for you, which is why that works when you check that option.
And don't forget to makeKeyAndVisible:
[self.window makeKeyAndVisible];
Thus:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *firstVC = [storyboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: firstVC];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}

top bar not visible after programmatically pushing UINavigationController

In the AppDelegate i check if there is a user existing, if there is i "skip" two ViewControllers by pushing a NavigationController using this code:
if(currentUser){
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"Test"];
self.window.rootViewController = viewController;
viewController.navigationController.navigationBarHidden = NO; // Tried this nothing happened.
[self.window makeKeyAndVisible];
}
else{
[PFUser enableAutomaticUser];
[[PFUser currentUser] incrementKey:#"RunCount"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] fetch];
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"firstView"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
}
So the true statement skips two ViewControllers and push the UINavigationController. But when it shows it this way there is no top bar.
However if there was no user then it would proceed to the UINavigationController in a "normal" way by segues then the bar is visible.
How can i fix this?
Thank you!
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
UIViewController *viewController = [storyboard
instantiateViewControllerWithIdentifier:#"Test"];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window.rootViewController = nav;
"So the true statement skips two ViewControllers and push the UINavigationController." No, it doesn't. First of all you're not pushing anything, you're setting the window's root view controller. Secondly, you haven't created any navigation controller, you've only created viewController.
If viewController has a navigation controller in the storyboard, then you should instantiate the navigation controller (which will, in turn, instantiate viewController), and make it the window's root view controller.
I think you should set a UINavigationController to rootviewController , there will be a navigation bar. So you can also set the firstView as rootViewController, but set the viewcontrollers attribute to put the Test viewcontroller that clears before viewcontrollers.

iOS- navigate From AppDelegate to certain item in slidemenu

I use swrevealviewcontroller to add slide menu to my app ,
Let consider we have menu like this one in pic
I need navigate from My appDelegate to any item in menu (ex:Map View Controller )
my tries :
in my appDelegate.m
UIStoryboard *storyboard =[UIStoryboard storyboardWithName:#"Main" bundle:nil];
InforView *school_view = [storyboard instantiateViewControllerWithIdentifier:#"info_view"];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:school_view animated:YES completion:NULL];
When its move to InforView Controller it crash in viewdidload
- (void)viewDidLoad
{
[super viewDidLoad];
_nav_bar.target = self.revealViewController;
_nav_bar.action = #selector(revealToggle:);
// its crash here
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
my storyboard
navigation controller --> home view --> reveal View controller
reveal View controller has two views --> slide menu
navigation controller -- > Front view
my slide menu has some items as appear in pic
I need navigate from my appDelegate to one of this items
Finally I find the answer
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
// this any item in list you want navigate to
Home_tableView *home = (Home_tableView *) [storyboard instantiateViewControllerWithIdentifier:#"home_view"];
SlideMenu *slidemenu = (SlideMenu *)[storyboard instantiateViewControllerWithIdentifier:#"Menu_view"];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:home];
UINavigationController *smVC = [[UINavigationController alloc]initWithRootViewController:slidemenu];
// define rear and frontviewcontroller
SWRevealViewController *revealController = [[SWRevealViewController alloc]initWithRearViewController:smVC frontViewController:nav];
// make it as root
self.window.rootViewController = revealController;
In the SidebarDemo project, you can use the following code to show MapViewController on initial loading.
SWRevealViewController *revealViewController = (SWRevealViewController*)self.window.rootViewController;
UIStoryboard *storyboard =[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MapViewController *mapVC = [storyboard instantiateViewControllerWithIdentifier:#"MapID"];
[self.window makeKeyAndVisible];
UINavigationController* navController = (UINavigationController*)revealViewController.frontViewController;
[navController setViewControllers: #[mapVC] animated: NO ];
[revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
After makeKeyAndVisible, the frontViewController and realViewController of the revealViewController are loaded. And you can set rootViewController of frontViewController, which is a navigationController.

Creating UITabBarController in a UINavigationController

My app has a drawer menu view and some content views.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
// Side menu view controller
UIViewController *menuViewController = [storyboard instantiateViewControllerWithIdentifier:#"sidebar_menu"];
UINavigationController *menuNav = [[UINavigationController alloc] initWithRootViewController:menuViewController];
// The initial content view controller
UIViewController *contentViewController = [storyboard instantiateViewControllerWithIdentifier:#"content1"];
UINavigationController *contentNav = [[UINavigationController alloc] initWithRootViewController:contentViewController];
NVSlideMenuController *slideMenuController = [[NVSlideMenuController alloc] initWithMenuViewController:menuNav andContentViewController:contentNav];
slideMenuController.slideDirection = NVSlideMenuControllerSlideFromRightToLeft;
self.window.rootViewController = slideMenuController;
[self.window makeKeyAndVisible];
}
I want to insert a tab bar controller programatically to content view. I want the change the current content view to another content view when the tab bar item button pressed.
Is it possible to create this kind of structure? How could I achieve this?
You simply need to code that you've just described in the question. Here is how you can modify your code to add UITabBarController that wraps your contentViewController, I've changed The initial content view controller section:
// The initial content view controller
UIViewController *contentViewController = [storyboard instantiateViewControllerWithIdentifier:#"content1"];
[contentViewController setTabBarItem:[[UITabBarItem alloc] initWithTitle:#"My Content" image:[UIImage new] tag:1]];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:#[contentViewController/* you can add more view controllers if needed*/]];
UINavigationController *contentNav = [[UINavigationController alloc] initWithRootViewController:tabBarController];

ios adding navigation before splitview controller

I want to add a navigation view controller prior to the user getting to the splitview controller. I have tried a few ways of changing the root controller when I want to go from navigation controller to splitview controller but I don't seem to be setting the delegate the right way when I do this.
Code WITHOUT nav view (works perfectly):
AppDelegate
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
MasterViewController *controller = (MasterViewController *)masterNavigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
Code with nav view prior to SplitView
AppDelegate
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController* rootController = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"dummy"];
self.window.rootViewController = rootController;
[self.window makeKeyAndVisible];
DummyViewController
AppDelegate *appDelegateTemp = [[UIApplication sharedApplication]delegate];
appDelegateTemp.window.rootViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateInitialViewController];
This takes me from the DummyViewController that I launched into, to the splitview controller which is the initial view controller in Storyboard. Which is fine however, when I do it this way none of the delegates get called. This is probably because when changing root controllers, it is not setting the delegates properly. How can I get this to work the right way?
It seems the only really non-hacking way to do it is to present a modal view over the split view in the detail view controller
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
DummyViewController *dummy = (DummyViewController *)[storyboard instantiateViewControllerWithIdentifier:#"dummy"];
[self presentViewController:dummy animated:NO completion:nil];
By setting animation to NO, the user does not see the split view loaded behind it.

Resources