This issue only occurs on iPhone 5, regardless of iOS version.
I present the secondViewController from the firstViewController it
is presented this time.
I then dismiss the secondViewController.
I attempt to present the secondViewController again from the
firstViewController, this time it isn't presented but the UI is blocked,
From logging the process I can see that viewWillAppear method is called the first time but not the second time.
FirstViewController
- (void)presentView {
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:secondViewController animated:YES completion:nil];
}
SecondViewController
- (void)dismissView {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
Related
When the user clicks on a button I am displaying a UIViewController as follows:
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"newviews"];
[self presentViewController:vc animated:YES completion:nil];
However, when the vc viewcontroller loads successfully, the user will click on another button and another UIViewcontroller is displayed. Again this too uses a presentViewController: as in the previous code.
Now, there's 2 UIViewController that's being displayed by presentViewController:,
When the user clicks on a button I need these 2 ViewControllers to Dismiss. How can I do this ?
I tried the following code but it did not work.
[self.navigationController popToRootViewControllerAnimated:YES];
You need to use [self.parentViewController dismissViewControllerAnimated:YES] since you presented them modally. You can take advantage of the parentViewController property when dismissing viewControllers.
UIViewController *mainController = [UIViewController new];
UIViewController *vcA = [UIViewController new];
UIViewController *vcB = [UIViewController new];
// User taps button to present vcA
[mainController presentViewController:vcA animated:YES completion:nil];
// User taps button to present vcB
[vcA presentViewController:vcB animated:YES completion:nil];
// Dismiss both vcB and vcA
[vcB.parentViewController dismissViewControllerAnimated:YES completion:^{
[vcA.parentViewController dismissViewControllerAnimated:YES completion:^{
// Now you are back on mainController
}];
}];
In a view that was created modally, pressing a button causes the modal view to be dismissed and another modal view to load.
- (void)loadLanguageSelectionView {
[self dismissViewControllerAnimated:YES completion:nil];
UIViewController *languageSelectionController = [[LanguageSelectionViewController alloc] initWithNibName:nil bundle:nil];
[languageSelectionController setModalPresentationStyle:UIModalPresentationCustom];
[languageSelectionController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:languageSelectionController animated:YES completion:nil];
}
The following error is thrown when this code block executes:
DenkoStation[4259:73173] Warning: Attempt to present <LanguageSelectionViewController: 0x7b185430> on <ViewController: 0x79f52e50> whose view is not in the window hierarchy!
What surprises me is the fact that the code was running happily before I made some changes to my code as outlined here.
Where's the mistake?
Because you are trying to present a viewController on top of a viewController which is already dismissed and no longer in window hierarchy.
What you can try is, you can take the ParentViewController reference from current viewController and then you can present new viewController on ParentViewController Like This :
- (void)loadLanguageSelectionView {
UIViewController *parentController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
UIViewController *languageSelectionController = [[LanguageSelectionViewController alloc] initWithNibName:nil bundle:nil];
[languageSelectionController setModalPresentationStyle:UIModalPresentationCustom];
[languageSelectionController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[parentController presentViewController:languageSelectionController animated:YES completion:nil];
}];
}
I have a photo selection flow that that goes as such:
VC1 push to VC2, present modal, dismiss modal, push VC3.
Upon dismissing the modal view however, self.navigationController is null
Modal View:
[self dismissViewControllerAnimated:YES completion:^{
FBGalleryVC *vc = [[FBGalleryVC alloc] init];
[vc showVC3];
}];
Triggers VC2:
- (void)showVC3 {
NSLog(#"NavController=%#",self.navigationController);
VC3 *vc3 = [self.storyboard instantiateViewControllerWithIdentifier:#"VC3"];
[self.navigationController pushViewController:vc3 animated:YES];
}
It's unclear to me why the navigationController is getting 'unset' or returning as null.
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];
}
In my app i present a UINavigationController modally with a UIViewController as its rootViewController. I do it in form style. I added a second UIViewController which is also in form style and i can push to it fine. However when i perform a popViewController action after the second UIViewcontroller gets popped onto the first, the whole modally presented UIViewController gets dismissed. However i don't perform any dismissing and the dismissing function doesn't get triggered by accident either.
Any ideas why it's happening?
Sincerely,
Zoli
EDIT:
That's how i'm presenting the modal viewcontrollers with a navcontroller:
if(!welcomeScreenAlreadyPresented) {
welcomeScreenViewController = [[WAWelcomeViewController alloc]init];
}
welcomeScreenNavController = [[UINavigationController alloc]initWithRootViewController:welcomeScreenViewController];
[welcomeScreenNavController setModalTransitionStyle: UIModalTransitionStyleCrossDissolve];
[welcomeScreenNavController setModalPresentationStyle:UIModalPresentationFormSheet];
[welcomeScreenNavController setNavigationBarHidden:YES animated:NO];
[self.navigationController presentViewController:welcomeScreenNavController animated:YES completion:nil];
That's how i'm navigation in WAWelcomeViewController.m
registerViewController = [[WARegisterViewController alloc]init];
[self.navigationController pushViewController:registerViewController animated:YES];
And in WARegisterViewController.m that's how i pop back
[self.navigationController popViewControllerAnimated:YES];
What you need to do is put the viewController you want to push inside another UINavigationController.
registerViewController = [[WARegisterViewController alloc]init];
UINavigationController *modalNavigationController = [[UINavigationController alloc] initWithRootViewController:registerViewController]; // autorelease if you are not using ARC
[self presentViewController:navController animated:YES completion:^{}];
You might want to add the modalNavigationController as a property to later call popViewControllerAnimated: on it.