Is there a way to dismiss the current ViewController after presenting another? - ios

After some time searching for an answer, I have to admit that i'm pretty confuse with this case.
At my job, I'm asked to do something really specific :
I have to present a UIViewController on a previous UIViewController, actually, the current ViewController dismiss itself before the second appear. That give the whole thing a funny animation that a ViewController goes down and another rise from the bottom after this. But... It's not really "pro" and, we're able to see the rootViewController behind the scene during the animation.
So, I have to precise that there is NO NavigationController, that would have made this a lot easier in my opinion, so I'm forced to do it with two UIViewController, and there is my actual code :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"userViewController"];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:controller animated:YES completion:^{
[self dismissViewControllerAnimated:YES completion:nil];
}];
It is call right after a button is pressed, so there is no problem with the actual ViewController viewDidLoad or viewDidAppear I think.
But each time this code runs, I get the following error :
[1163:17641] Warning: Attempt to present <UserViewController: 0x7b0f0a00> on <EIHomeViewController: 0x7b0d2a00> whose view is not in the window hierarchy!
I don't really know how I could manage to keep a trace of the current UIViewController to dismiss it in the next ViewController viewDidAppear to be sure there will be no "blackout" on the screen.
Thank you for your help in advance!

Try this code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"userViewController"];
[self dismissViewControllerAnimated:NO completion:^{
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:controller animated:NO completion:nil];
}];

Related

Going back and forth between UIViewController while keeping the states of the views

I have two view controllers, PlayViewController and ShopViewController.
The goal is to go from PlayViewController to ShopViewController, and back.
To go to the shopController I use this code:
UIStoryboard* mainStoryBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
ShopViewController* vc = [mainStoryBoard instantiateViewControllerWithIdentifier:#"ShopViewController"];
vc.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[vc setGameLevelManager:[[playViewController getCentralUIManager] getGameManager]];
[vc setUIViewControllerOrigin:nil PlayerViewController:playViewController];
[playViewController presentViewController:vc animated:YES completion:nil];
The code above works, user jumps from the PlayViewController to the ShopViewController.
Now when jumping back from the ShopViewController to PlayViewController I use the following code:
playViewController.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentViewController:playViewController animated:YES completion:nil];
The Code above does go back to the PlayViewController, but call for the viewDidLoad and re-initiate the view from the beginning. Thing is that when i call ShopViewController from PlayViewController, I have additional window shown in the View, namely the LevelFailure view. When ViewDidLoad, it completely forget about what was displayed when the user went to ShopViewController.
I am sure there is a way to go back to PlayViewController and have the states , and views back how they were , but I could not identify the approach yet.
If you would have any thoughts about the matter, there would be more than welcome!

How to call a View Controller from not related View Controller programmatically?

as you see on the image, on the normal case I click the button1 to call the second view and then I click the button2 to call the last view, and in a particular scenario I want to click the button1 to call the last view.
I added this on the methode viewDidLoad:
if(condition)
[self performSegueWithIdentifier:#"thirdview" sender:self];
but it is not working, any help please.
thank you.
You need to add a segue from ViewController1 to Viewcontroller3.
But if you do this with many viewControllers then it becomes messy, I call it the spaguetti segues.
The alternative is to present that viewController modally.
Example:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
ViewController3 *viewController =
[storyboard instantiateViewControllerWithIdentifier:#"viewController"];
[self presentViewController:viewController animated:YES completion:nil];
(make sure you give ViewController3 a storyboardId)

Removing ViewController after showing modally a second ViewController

Guys in my app I have some code in the app delegate method application:didFinishLaunchingWithOptions: that determines if the initial View Controller should be the LoginViewController or the MainViewController.
If the LoginViewController is showed first and the user logs in successfully I show the MainViewController modally with this piece of code:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FSMainViewController *vc = (MainViewController *)[storyBoard instantiateViewControllerWithIdentifier:#"MainViewController"];
vc.loginViewController = self;
[self presentViewController:vc animated:YES completion:nil];
What I want to do next, after the MainController is showed on the screen, is remove the LoginViewController from memory so in the viewWillApper:animated: method of the MainViewController I use this code to remove (or at least try to) the LoginViewController:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.loginViewController) {
[self.loginViewController dismissViewControllerAnimated:NO completion:nil];
}
}
Problem is that this code leads to strange behaviors like the MainViewController being removed from the screen and this error message showing up in the console.
Unbalanced calls to begin/end appearance transitions for <LoginViewController: 0xb06e350>
I also tried calling [self dismissViewControllerAnimated:NO completion:nil] in the completion block of the presentViewController:animated:completion method but still no luck, it didn't work.
What am I doing wrong? How can I remove from memory the underlying LoginViewController when the MainViewController is presented modally?
Don't present your main view controller if you want the login controller to go away, just make it the window's root view controller.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FSMainViewController *vc = (MainViewController *)[storyBoard instantiateViewControllerWithIdentifier:#"MainViewController"];
Self.window.rootViewController = VC;
You can't dismissViewController after presenting another one on it or its presentingViewController. At here, you should dismiss LoginViewController first, then present MainViewController.
Otherwise, if you'd like pushViewController, you can call [self.navigationController setViewControllers: animated:] to remove LoginViewController.
If you think presentingViewController is just what you want, try something like this in application:didFinishLaunchingWithOptions:
if (self.loginViewController) { //Define loginViewController in appDelegate.h
[self dismissViewControllerAnimated:NO completion:^{
[self presentViewController:mainViewController animated:YES completion:nil];
}];
}
else{
[self presentViewController:mainViewController animated:YES completion:nil];
}

self.tabBarController dismissViewControllerAnimated doesn't work

I have a UITabBarController in my application.
I would like to present from one tab, another UIViewController.
So I wrote in ViewControllerA (which is a tab in the tabviewcontroller):
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MyViewController *chooseTemplateController = [storyboard instantiateViewControllerWithIdentifier:#"myController"];
[self.tabBarController presentViewController:myController animated:NO completion:nil];
This shows MyViewController nicely.
However, how can I dismiss MyViewController?
I read in many questions that I need to call:
[self.tabBarController dismissViewControllerAnimated:NO completion:nil];
However - where do I call it from? I tried from MyViewController - but since it's not part of the UITabBar, self.tabBarController is null.
I initialize the UiTabBarController from storyboard and not from appDelegate and I would like to leave it that way.
Use the presented viewController's presentingViewController property
Objective-C
[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
Swift
presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
You can also use this shorthand version (I don't recommend you do, but you will see it often)
Objective-C
[self dismissViewControllerAnimated:NO completion:nil];
Swift
dismissViewControllerAnimated(false, completion: nil)
see
Dismissing a Presented View Controller

Transition between two UIViewControllers with no animation

From my appDelegate I load the the homeScreen ViewController like this:
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
UIViewController *controller = [sb instantiateViewControllerWithIdentifier:#"HomeScreen"];
[self.window setRootViewController:controller];
The app only ever then changes between my 'homeScreen' and 'PlayViewController' ViewControllers and that is done like this:
PlayViewControlller* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"PlayViewController"];
[self presentModalViewController:vc animated:NO];
and this
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
UIViewController *controller = [sb instantiateViewControllerWithIdentifier:#"HomeScreen"];
[self presentModalViewController:controller animated:NO];
respectively.
This all works fine. I am able to switch between the viewcontrollers with uibuttons and the above code. However, I'm not sure what causes this, it happens after I've switched between the two viewcontrollers a few times, but the transition starts to get animated and they start twirling when switching.
Ok so I'm trying to narrow down the problem and see what's causing it. I think its the other animation blocks that I'm using in my app. But there's a lot there so don't know exactly what it is.
OK so I found the line of code that was causing this if anyone happens to find themselves in the same situation.
[UIView beginAnimations:#"Move" context:NULL];

Resources