Objective-C: whose view is not in the window hierarchy - ios

I have this code that works so that once i press a button the view changes in my storyboard:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewController *viewController = (ViewController *)[storyboard instantiateViewControllerWithIdentifier:#"view1"];
[self presentViewController:viewController animated:YES completion:nil];
This code work but when i use it again to change back to my original view using:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewController *viewController = (ViewController *)[storyboard instantiateViewControllerWithIdentifier:#"view2"];
[self presentViewController:viewController animated:YES completion:nil];
It does not work and i receive this error:
Warning: Attempt to present <UIViewController: 0x863ad30> on <UITabBarController: 0x86309b0> whose view is not in the window hierarchy!
The identifies are set and i am not the functions in my viewdidload so i do not know how to fix this.
Can anybody help?

Try this,
First Method
-(IBAction)signin:(id)sender
{
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"viewController"];
[[[[UIApplication sharedApplication] delegate] window] setRootViewController:vc];
}
Second method (to return back to the previous view)
- (IBAction)signout:(id)sender
{
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"parentViewController"];
[[[[UIApplication sharedApplication] delegate] window] setRootViewController:vc];
}

This might happen if you call the method before calling makeKeyAndVisible, so move the calling after that.
If not try the hack below:
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:viewController animated:YES completion:nil];

The error message says all: you have to add the view controller's view to the window before presenting the view controller:
UIWindow* keyWindow= [[UIApplication sharedApplication] keyWindow];
[keyWindow addSubview: viewController.view];
[self presentViewController:viewController animated:YES completion:nil];

Related

Remove a view from controller from any other class?

I have three screens Google Map,Settings,Login.By default google map is visible.When i want to show settings screen then i don't move to settings view controller i just add "Settings"screen as subview of "Google Map"Screen.
menusettings=[self.storyboard instantiateViewControllerWithIdentifier:#"SET"];
[menusettings.view setFrame:CGRectMake(0, 0, 700,600)];
[self.view addSubview:menusettings.view];
After upadating settings i move to login screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"iPhone" bundle:nil];
UINavigationController *ppc = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:ppc animated:true completion:nil];
But settings screen is still behind login screen but it is not removed. I tried two scenerios
1.I tried to remove settings view before moving to login screen
[self.view removeFromSuperview];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"PRG_iPhone" bundle:nil];
UINavigationController *ppc = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:ppc animated:true completion:nil];
but it does not move to login screen.
2.When i tried removing settings view after moving to login screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"PRG_iPhone" bundle:nil];
UINavigationController *ppc = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:ppc animated:true completion:nil];
[self.view removefromsuperview];
Then it moved to login screen but does not remove settings view
So i thought why not remove Google Map Screen's subview which is setting screen from login screen but i don't know how can i remove a google map screen child view which is settings screen.Please guide how to do this ?
Change this
[self.view removeFromSuperview];
to and try
[menusettings.view removeFromSuperview];
update
[menusettings.view removeFromSuperview];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"PRG_iPhone" bundle:nil];
UINavigationController *ppc = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:ppc animated:true completion:nil];
Choice-1
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
choice-2
Initially assign the tag for your View for e.g
menusettings=[self.storyboard instantiateViewControllerWithIdentifier:#"SET"];
[menusettings.view setFrame:CGRectMake(0, 0, 700,600)];
menusettings.tag = 5; //you can use any number you like
[self.view addSubview:menusettings.view];
Remove
UIView *Remove = [self.view viewWithTag:5];
[Remove removeFromSuperview];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"PRG_iPhone" bundle:nil];
UINavigationController *ppc = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"LOGIN"];
[self presentViewController:ppc animated:true completion:nil];
Choice-3
for (UIView *subVie in self.view.subviews)
{
if (subVie.tag == 5)
{
[subVie removeFromSuperview];
}
}

Dismiss to other storyboard

In my project i have 2 storyboards. One for login and one for the main.
After login is complete i present the main storyboard using this method:
-(void)successLogin {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateInitialViewController];
[self presentViewController:vc animated:YES completion:nil];
}
My question is how do I get back to the login storyboard if i want to put logout button in the main storyboard. I tried doing the following:
[self dismissViewControllerAnimated:YES completion:nil];
And it still doesn't work.
try this on LOGOUT click event:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginviewController *Login = [storyboard instantiateViewControllerWithIdentifier:#"LoginviewController"];
[self.navigationController pushViewController:Login animated:YES];
try to set one view controller as root view controller then present another view controller.
[[[UIApplication sharedApplication] keyWindow] setRootViewController:viewController];
[viewController presentViewController:VC animated:YES completion:nil];
you will come to the rootViewController when you dismissViewControllerAnimated:
logout success
Try this code it works for you
-(void)successlogout
{
//[self dismissViewControllerAnimated:NO completion:nil];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
login *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"login"];
[self presentViewController:vc animated:NO completion:nil];
}

How to pass property to root view controller while presenting UINavigationController?

I'm doing in-app browser to open links w-out using safari from any viewController in app.
This is a code for launching browser with link in AppDelegate.m
-(void)openExternalRef:(NSString *)ref
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
CSDBrowser* browser = [storyboard instantiateViewControllerWithIdentifier:#"CSDBrowser"];
browser.urlString = ref;
browser.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.window makeKeyAndVisible];
UINavigationController* navi = [storyboard instantiateViewControllerWithIdentifier:#"CSDBrowserNavi"];
[self.window.rootViewController presentViewController:navi animated:YES completion:nil];
[self.window.rootViewController.navigationController pushViewController:browser animated:YES];
}
i need to pass a variable "ref" to my viewcontroller, but i need to launch navigation controller first, any ideas?
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
[self.window makeKeyAndVisible];
UINavigationController* navi = [storyboard instantiateViewControllerWithIdentifier:#"CSDBrowserNavi"];
CSDBrowser* browser = [navi viewControllers][0];
browser.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
browser.urlString = ref;
[self.window.rootViewController presentViewController:navi animated:YES completion:nil];

Game Center: Matchmaking

In my card playing game I am trying to create a match, which, for a part, works;
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match {
self.match = match;
match.delegate = self;
if (!_matchStarted && match.expectedPlayerCount == 0) {
NSLog(#"Ready to start match!");
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"GameVC"];
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[viewController presentViewController:vc animated:YES completion:nil];
//[viewController dismissViewControllerAnimated:YES completion:nil];
}
}
After a match is created successfully I want the GKMatchmakerViewController to be dismissed and I want the "vc" UIViewController to be shown. In the above example this is accomplished, but the GKMatchmakerViewController does not get dismissed.
If I remove the comment quotes it will be loaded after it got dismissed somehow and if I place the line above the presentViewController line I get an error stating that I am trying to present a view controller on a view controller that is not in the view hierarchy.
How do I dismiss the GKMVC and show the "vc" at the "same" time?
Thanks!
You need to dismiss the GKMatchMakerViewController, then use your current view controller to present the new modal:
if (!_matchStarted && match.expectedPlayerCount == 0) {
NSLog(#"Ready to start match!");
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"GameVC"];
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[viewController dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:vc animated:YES completion:nil];
}
Edit: A trick to get the current root view controller is [[UIApplication sharedApplication] delegate].window.rootViewController. So you should be able to present your modal with this:
[[[UIApplication sharedApplication] delegate].window.rootViewController presentViewController:vc animated:YES completion:nil];

How to pass data to ViewController, using UIViewController

How to pass data to ViewController using this code?
UIStoryboard *main = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [main instantiateViewControllerWithIdentifier:#"Catalog"];
[self presentViewController:vc animated:YES completion:nil];
I want to pass data in example to itemId, like here:
ViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
vc.itemId = 0;
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:vc animated:YES completion:nil];
Type cast your UIViewController if it's ViewController
ViewController *vc = (ViewController*)[main instantiateViewControllerWithIdentifier:#"Catalog"];
vc.itemId = 0;
[self presentViewController:vc animated:YES completion:nil];
This should also work for you.
ViewController *vc=[self.storyboard instantiateViewControllerWithIdentifier:#"Catalog"];
vc.itemId =0;
[self presentViewController:vc animated:YES completion:Nil];

Resources