Dismissing Modal View Controller Causes Multiple VC's to Close - ios

This question is hard for me to ask without a reference, so please see the image above. I am trying to dismiss the modal view controller on the far right of my storyboard.
The problem is when the view controller on the right hand side it dismissed and the user is returned to the middle view controller in the storyboard above, then immediately the next two view controllers are dismissed and the user is returned to the left most view controller.
I have only called the dismiss method on the right most view controller. I am wondering why this happens?
I have fiddled with the kind and presentation style of the segue to no avail. I have also tried using delegation and calling the dismiss method in the presenting view controller. This still results in the same unexpected behavior.
Any help would be great.

Related

Dismissing and presenting View Controllers - An Explanation?

Recently, I've been reading about the concepts behind dismissing and presenting View Controller. I've been able to pick up on the ideas of dismissing the previous View Controller from the destination View Controller but I can't find an answer to a few questions that have been on my mind for quite a bit.
Scenario 1: I have a login page and after the user enters their credentials, it performs a segue to another View Controller. Is it necessary to dismiss the login page afterwards or is there no reason to?
Scenario 2: I have two normal View Controllers (VC1 and VC2). If I perform a segue to VC2, will I need to dismiss VC1?
I'm mainly confused regarding the idea of when it is necessary to dismiss View Controllers and when it is not necessary to do so.
I'd appreciate it if anybody could help clear these questions up for me.
Scenario 1: After performing a segue, it switches between your view controllers [ automatically dismisses the current ViewController and presents a new one ].
So, there's no reason to dismiss the login page.
Scenario 2: No you don't need to dismiss VC1.
1) When you go from login controller to second controller you just need to present the second controller and no need to dismiss first because if you are using navigation controller as a part of your segue all the view controllers are arranged in form of a stack . So second comes on top and first goes below it.Now if you need to got from second to first you can either dismiss your controller or pop your controller.When you dismiss a controller it is not popped from stack instead just moves behind and let the first controller come on top and when you pop a controller it removes itself from stack as well.
2) Same goes for your second question no need to dismiss first when you go from first to second controller.
If there is a view controller which in most cases will be used only once (like login or settings etc.) — and especially if, after you’re done with it, it makes sense to return to the view controller you were on before — the best is to present it modally and dismiss it when you’re done. The rest of your view controllers stay in memory after the user can no longer see them, and this is expected behavior given the way Apple has created the methods for presenting and dismissing view controllers.
It is my understanding that in the Android world, this is not the case -- the default there is that when a new view controller is presented, the old one really does goes away.
As you know once user has signed in, log in screen not opens until user log out. So you should remove log in view controller from stack, it should not keep in memory. For this task, do not directly perform segue, you should change root view controller. There are lot of answers on stackoverflow for How to change root view controller?

Is it possible to segue from a modal view to a view that is not in the hierarchy on a Navigation Controller in swift?

On my main view in a NavigationController I have a button that brings up a new view modally to submit a post. I have a button to dismiss this view which brings the user back to the main view, however if the users proceeds to make a post, I want it to dismiss the view and proceed to a show the post in the Navigation controller.
The ideal effect would have the standard navigation controller's back button on the top that can bring the user back to the main view when they have finished looking at their post.
I have tried several different methods, but I tend to get an error stating "Warning: Attempt to present (The View I Want to Show) whose view is not in the window hierarchy!
Thanks for any info!
Yes, it's possible. This is the best way I've found to structure the app to allow this functionality.
RootViewController
UINavigationViewController
ContentViewController (your current "main" view controller)
You're basically going to create a new RootViewController that is going to contain your current UINavigationController as a child. I usually setup the window.rootViewController programmatically in the AppDelegate. I would also keep a global reference to it.
Have a look at Apple's documentation on this. Basically, the RootViewController code would look like this:
[self addChildViewController:navController];
navController.view.frame = self.view.bounds
[self.view addSubview:self.navController.view];
[navController didMoveToParentViewController:self];
Now, whenever you need to present a modal view controller, present it from the RootViewController, instead of the current/top view controller on the UINavigationBar. This allows you to manipulate the UINavigtaionController independently and you won't get the error you're seeing.
So present the modal view controller from the RootViewController, this covers the UINavigationController and its content (top view controller). Make any changes you need to the UINavigationController stack (push, pop, etc...) with no animation. When you're done dismiss the modal view controller (with animation) and it will show you're adjusted UINavigationController.
Hopefully, this all makes sense. It's kind of complex and hard to explain in text. :p
If you don't want to setup a RootViewController, you might want to try presenting the modal view controller from the UINavigationController, as that might have the same effect. From the view controller just do self.parentViewController.present.
The main thing you're trying to avoid is presenting a modal from a view controller and then removing that view controller (pop) before the modal is dismissed. The view controller that presents the view controller is responsible for dismissing it.
I finally got it all working (I'm still new to Swift) and the two comments on the question were very helpful. The most helpful of all was the top answer here's example on github.
Similar question

Dismissing View controllers and then presenting them

I have an application that has 3 view controllers.
The first one presents the second one and the second one then presents the third one. I then have a button that I want to bring me back to the first view controller. This button works. However, I try to present the 2nd view controller from the first and then the 3rd view controller from the 2nd again. Presenting the 2nd view controller works fine, but presenting the 3rd view controller doesn't work. I get the error:
Warning: Attempt to present on whose view is not in the window hierarchy!
The first view controller is the main menu to the game, the second view controller is where the game occurs and the third view controller is the end result screen. Is there a better way to do it than my way?
Does anyone have a solution? Thanks in advance.
You have to use a navigation controller. All you're doing now is pushing views in an infinite loop.
Here is a really good site to read with examples.
http://www.mysamplecode.com/2013/01/ios-navigation-view-controller-example.html

How to dismiss a NavigationController in Storyboard?

I've looked everywhere for this, so as a last resort I figured I should ask the question.
I'm using Storyboard in XCode and have a navigation controller as my initial view. The root view of this navigation controller is a table view. In this table view, I have a button in the navigation bar that flips the view horizontally via a modal segue to a navigation controller. The root view of this controller is my map view. Now, when I want to dismiss this map view using [self dismissViewControllerAnimated:YES completion:nil] it doesn't work. It does if I take out the navigation controller. So, I'm guessing the dismissViewController is getting passed to the navigation controller, and not doing anything. I know I could implement a class for the navigation controller to handle the call and pass it on, but I don't want to do that unless absolutely necessary.
So to solve this question:
I need a way to switch between table view to map view using the flip horizontally animation and vice versa.
I need to have a navigation controller in both views, I could either be the same one, or a different one. I can't seem to find a way to use the same one, since any transitions would be pushes which don't do the flip horizontally transition.
Thanks in advance for the help!
Who is self when you call [self dismissViewControllerAnimated:YES completion:nil]?
The receiver of this message needs to be the view controller which presented the modal view controller you want to dismiss. If you call it on the presented view controller, or (in the case of container view controllers like UINavigationController, one of the view controllers it manages), UIKit will try to do the right thing but won't always succeed.
Presuming the self you refer to is the view controller containing the map view, you can get the presentingViewController property to get the object you should call dismissViewControllerAnimated:completion: on. (And if you need to get the navigation controller that's in between, use the navigationController property.)

Why does a modal view controller disappear after switching apps?

I am displaying a modal view controller in my app. When I switch to a different app and then back to mine, the modal view controller is no longer displayed, what I see instead is the view behind it.
I know that the modal view controller is still in the view hierarchy and is simply not drawn, because I can call dismissModalViewController on the parent view controller and the app will behave correctly (if I don't call dismissModalViewController, displaying another modal view controller puts the app into a weird state).
Has anyone else encountered this? What can be done to fix it?
There is a thing you should try: try using some "well known" View Controller instead of the one you display and see if you get the same result with disappearance. Like UIImagePickerViewController

Resources