ViewDeck removes navigation bar when setting center controller - ios

I am currently using ViewDeck with Storyboards, and have the following setup in the application didFinishLaunchingWithOptions:
//View Deck Setup
UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController* menuController = [mainStoryboard instantiateViewControllerWithIdentifier:#"LeftSideMenu"];
UINavigationController* navigationController = (UINavigationController *) self.window.rootViewController;
self.viewDeckController = [[IIViewDeckController alloc] initWithCenterViewController:navigationController leftViewController:menuController rightViewController:nil];
self.window.rootViewController = self.viewDeckController;
However, when I am setting a new CenterController from my MenuViewController, the navigation bar is removed, even if loading the same center view controller as I was previously looking at.
- (IBAction)viewUsers:(UIButton *)sender
{
UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController* viewController = [mainStoryboard instantiateViewControllerWithIdentifier:#"middleViewController"];
[self.viewDeckController setCenterController:viewController];
[self.viewDeckController closeLeftView];
}
What am I doing incorrectly?

The solution is remove any "deck constructor" class between AppDelegate and you TabBar. When you need to set or change Deck structure I create a several methods for each one structure. For example, if you want Deck has "leftView" view controller in left side, "rightView" in the right and "tabBarHome" in center, create a method like this in App Delegate:
-(void) lanzarHome{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
IIViewDeckController* deckController =[[IIViewDeckController alloc] initWithCenterViewController:[storyboard instantiateViewControllerWithIdentifier:#"tabBarHome"]
leftViewController:[storyboard instantiateViewControllerWithIdentifier:#"leftView"]
rightViewController:[storyboard instantiateViewControllerWithIdentifier:#"rightView"]];
deckController.leftSize = 100;
self.window.rootViewController = deckController;
[self.window makeKeyAndVisible];
}
Now, you must call this method from your viewController with sentence like this:
[((VKAppDelegate*) [[UIApplication sharedApplication] delegate]) lanzarHome];
The most important think is that create the method that changes or inits Deck structure from AppDelegate and never you have another class or viewController between delegate and center TabBar.
I hope this answer solve your issue. For me was a very hard work to find out this issue.

Related

Pushing view controller from AppDelegate

I am just beginning to learn how to implement Push notifications with iOS and Parse.
At the moment, I can send push notifications from the Parse dashboard to the app,the notification is received, as I can see in the Xcode console, but now my issue is that I am not able to open a view controller from the AppDelegate.
This is my code:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
// Create empty photo object
NSString *photoId = [userInfo objectForKey:#"p"];
NSLog(#"P=%#",photoId);
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
Aceptado *targetViewController = (Aceptado*)[mainStoryboard instantiateViewControllerWithIdentifier:#"servicio_aceptado"];
UINavigationController *controlador = [[UINavigationController alloc]init];
[controlador pushViewController:targetViewController animated:YES];
}
As I said, the console show the log NSLog(#"P=%#",photoId) , the notification is received, but the view controller is not shown, any warning or error is shown.
Any help is welcome.
I have solved my problem like this:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
Aceptado *controller = (Aceptado*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"servicio_aceptado"];
controller.id_not =_id_not;
controller.idemployee = _idemployee;
controller.fullname = _fullname;
controller.phone = _phone;
controller.photo = _photo;
controller.dni = _dni;
controller.licenseplate = _licenseplate;
controller.model = _model;
controller.color = _color;
controller.latitude = _latitude;
controller.longitude = _longitude;
self.window.rootViewController = controller;
Now I can pass values to the target view controller from the AppDelegate file, keeping the SWRevealViewController structure.
Thank to all of you for your proposals.
try this code.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
Aceptado *targetViewController = (Aceptado*)[mainStoryboard instantiateViewControllerWithIdentifier:#"servicio_aceptado"];
UINavigationController *navVc=(UINavigationController *) self.window.rootViewController;
[navVc pushViewController: targetViewController animated:YES];
may help you.
Try this once.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
Slider1ViewController *viewcontroller = [storyBoard instantiateViewControllerWithIdentifier:#"Slider1ViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewcontroller];
[navController setViewControllers: #[viewcontroller] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
You should not create new NavigationController, but use one existing. Usually it is rootViewController property of your key window.
Try this:
UINavigationController *controlador = self.window.rootViewController;
If you want to display your targetViewController in SWRevealViewController you may change your code as this:
SWRevealViewController *controlador = (SWRevealViewController)self.window.rootViewController;
[controloador pushFrontViewController:targetViewController animated:YES];
If you need display targetViewController over SWRevealViewController, use this:
WRevealViewController *controlador = (SWRevealViewController)self.window.rootViewController;
[controloador presentViewController:targetViewController
animated:YES
completion:nil];
If you need just replace SWRevealViewController with targetViewController use this:
self.window.rootviewController=targetViewController;
But don't forget save your SWRevealViewController in some another property.
Try this:
SomePageViewController *someVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SomeVC"];
self.navController = [[UINavigationController alloc] initWithRootViewController:someVC];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
If you want to push a view controller into navigation stack from appDelegate you need to cast your rootView controller as UINavigation Controller

Setting a RootViewController with UINavigationController Programmatically

I have a program with a Navigation Controller and a default RootViewController. If I do nothing programmatically, the app launches and the RootViewController works as I expect, such as what the storyboard below denotes:
The issue that I have is by incorporating the Optional Start ViewController. What I want is this: In my AppDelegate (didFinishLaunchingWithOptions), I want to have code like this:
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"OptionalStartViewController"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
To first show the Optional Start ViewController. Then, after the user has finished with the Optional viewcontroller, they can then display the RootViewController.
So in the Optional Start ViewController, I've added code like this to show the Root View Controller:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"RootViewController"];
[self appDelegate].window.rootViewController = viewController;
[[self appDelegate].window makeKeyAndVisible];
This all works except the RootViewController, when shown, does not have the navigation controls as expected (i.e. the view is shown without navigation controls).
I've also tried the code below (using UINavigationController instead of ViewController) with the same results...
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UINavigationController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
[self appDelegate].window.rootViewController = viewController;
[[self appDelegate].window makeKeyAndVisible];
One other twist... there could be several optional start view controllers.
Any ideas?
Delete the UINavigationController
select the controller ("optional start view controller" in our case)
click Editor >> Embed In >> Navigation Controller
Now select the Navigation Controller and Right Side Utility area, Select the option Is Initial View Controller
If you want to change the root view controller dynamically then its better to do it programmatically, in didFinishLaunchingWithOptions, Get the window instance , initialize navigation controller with the root view controller and then set windows root view controller to navigation controller.
Here is the code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
OptionalFirstViewController *optionalFirstViewController = [[OptionalFirstViewController alloc] initWithNibName:#"OptionalFirstViewController" bundle:nil];
UINavigationController *homeNavigationController = [[UINavigationController alloc] initWithRootViewController:optionalFirstViewController];
[optionalFirstViewController release];
self.window.rootViewController = homeNavigationController;
[homeNavigationController release];
[self.window makeKeyAndVisible];
return YES;
}
and make sure that you uncheck Is Initial View Controller for all view controllers in story board
Hope this helps
Without using storyboard we can set programmatically in AppDelegate Class, just write down these lines of code in AppDelegate.
AppDelegate.h
#property (strong, nonatomic) UIStoryboard *storyboard;
#property (strong, nonatomic) UINavigationController *navigationController;
AppDelegate.m
if(self.window == nil)
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
if(self.navigationController == nil)
self.navigationController = [[UINavigationController alloc]init];
if(self.storyboard == nil)
self.storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.navigationController.navigationBarHidden = YES;
// Here we can check user is login or not also,
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self.navigationController pushViewController:ivc animated:YES];
self.window.rootViewController = ivc;
[self.window setRootViewController:self.navigationController];
[self.window makeKeyAndVisible];
In Swift Version
var window: UIWindow?
var storyBoard :UIStoryboard?
var navigationController : UINavigationController?
var mainController :MainViewController = MainViewController()
if window == nil {
window = UIWindow(frame: UIScreen.main.bounds)
}
if navigationController == nil {
navigationController = UINavigationController()
}
if storyBoard == nil {
storyBoard = UIStoryboard(name: "Main", bundle:nil)
}
navigationController?.setNavigationBarHidden(true, animated: true)
// storyboard with identifer
mainController = storyBoard?.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
navigationController?.pushViewController(mainController , animated: true)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
You can't set a new root view controller to UINavigationController after it is initialised. You should modify viewControllers array of UINavigationController according to your needs.
If you want the optional VC to be root VC, create #[optionalVC] and set it as viewControllers array of UINavigationController.

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.

NavigationController Header Disappears when loading from AppDelegate

In my AppDelegates 'didFinishLaunchingWithOptions' function, I have this code in there:
if(loggedIn != nil)
{
MainViewController *mvc = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"MainView"];
[self.window setRootViewController:mvc];
}
Second Attempt which didn't work:
if(loggedIn != nil)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MainViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MainView"];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
[self.window setRootViewController:nav];
}
The problem is that when the MainViewController loads, the NavigationHeader is missing. I've tried various methods online and instantiations that basically do the same thing to no avail. I have also tried created a whole new navigationController and adding my view to it, however, that fails as well.
Your setting MainViewController as your root, if this is not a navigation controller, there will be no header when it opens.
Instead create a UINavigationController, set MainViewController as its root and then set the navigation controller as the window root.
e.g.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"storyboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"home"];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
[self.window setRootViewController:nav];
or if you have the navigation controller inside the storyboard then instantiate that. Most likely the initial view controller.
e.g.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"storyboardName" bundle:nil];
[self.window setRootViewController::[storyboard instantiateInitialViewController]];
not sure if it will be the initial viewController or not, that requires more info of your setup to know.

Load a specific controller in didReceiveRemoteNotification

I'm developing push notification on my app. I want that when people tap on push message, app open a specific controller;
If I do that with:
storyBoardName = #"MyStoryboardName";
UIStoryboard* storyBoard = [UIStoryboard storyboardWithName:storyBoardName bundle:nil];
MainWebController* MainWeb = [storyBoard instantiateViewControllerWithIdentifier:#"MainWeb"];
MainWeb.urlToLoad = URL_TO_LOAD;
self.window.rootViewController = MainWeb;
[self.window makeKeyAndVisible];
works, I can see MainWeb when i tap on push massage but the controller view cover all the screen: tab bar and navigation bar are hided!
I know that rootviewcontroller is a uitabbar:
NSLog(#"Controller: %#",self.window.rootViewController.debugDescription);
Solved with:
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
tabController.selectedIndex = 0;
UINavigationController *navigationController = (UINavigationController *)tabController.selectedViewController;
[navigationController pushViewController:MainWeb animated:YES];
You are replacing the rootViewController by setting it to be a MainWebController. Is this the initial UIViewController in your Storyboard?
From your issue it would seem that the initial UIViewConroller is a TabViewController and what you actually want is to setup a UIViewController inside this.

Resources