SplitViewController primaryViewController has no way of being dismissed - ios

I have a UISplitViewController with default behaviour. When showViewController(..) executes, it presents a new UINavigationController that I have passed. Sometimes this UINavigationController is presented modally (based on TraitCollection).
I have noticed that a UINavigationController (or any VC for that matter) is only presented modally when using a horizontally/vertically compact size class. What is missing however is a method of going back or simply dismissing the UINavigationController. (A back button is only visible if the device goes from compact-regular to regular-compact, in which case the UISplitViewController adds a back button to my presented UINavigationController.)
How do I handle this behavior to be as consistent as possible for dismissing this presented UINavigationController? Should I consider not using a UINavigationController for any particular reason? (and embed a ViewController only in certain cases instead?)
Any help appreciated.

Related

UINavigationController vs viewController embed in NavigationController

I was trying my hands on iOS and while building apps, one question get into mind that what is the difference between UINavigationController vs viewController embed in NavigationController.
While using UINavigationController we push and pop views.
while using viewController we present and dismiss.
SO what are the applications where one is more superior to use than the other.
UINavigationController is used where you want you move back and forth in your application. Generally Navigation controller is used when you are navigating in more detailed information in each level of depth you are in your application.
UIViewController is generally preferred when you display polished information. in UINavigationController generally it is the one of the last controller you push in your controller
I think you are really describing two sides to the same coin. There is only one way to use a UINavigationViewContorller. It is a known as a container view controller and its job is to push and pop other UIViewControllers. A UINavigationViewController works with viewControllers, not views.
UINavigationController:
If you have hierarchy of view controller then that is you have stack of view then you need to use navigation controller. You can perfrom push and pop operations on the view controller and Navigation Controller is the rootViewController of all ViewController.so to go back to the previous one, in a ordered way. Imagine that controllers in a navigation controller will just build a sequence from left to right.
UIViewController: if you are using view controller it act as presentViewController. The presentViewController offers a mechanism to display a so-called modal view controller; i.e., a view controller that will take full control of your UI by being superimposed on top of a presenting controller. I think that presentViewController is most suitable for use with just one view controller being presented at a time. So you simply will not be able to implement a "go back"/navigation like functionality.
UINavigationController inherits from UIViewController. The strange thing about this object model is the UIViewController has a property called NavigationController. So for OO purists this is a bit baffling that a parent class knows about its children. But moaning aside this is how it’s been done in UIKit. As you’ll find with a runtime error, you can’t place a UINavigationController inside a UINavigationController
Whenever you push a controller, it can access the parent UINavigationController it may or may not belong to via the NavigationController property. The property is null if the controller is not inside a UINavigationController.

Show(e.g. Push) from a viewcontroller to a navigation controller works?! Why?

So I am new to IOS programming and I am using the Swift language.
After doing a couple of beginner apps. I have had some trouble on figuring the difference between the Show(e.g. Push) and the deprecated Push segues.
What I want to do is to Show/Push from a ViewController A(embeded with Navigation Controller B ) to a Navigation Controller C (containing a View Controller D).
Since when I disable the "Use size classes", the Push segue doesn't work and will report error "pushing to a navigation controller is not supported". This error makes sense since you can only push regular view controllers.
However when I enable the "Use size classes" (which turns the Viewcontroller to a square instead of a rectangle), I was able to Show(e.g. Push) to a navigation controller, which really confuses me.
So what's the main difference between the Show(e.g. Push) and the deprecated Push? As to my knowledge there is no major functional difference but the fact seems to prove me wrong and makes me confused..
Update:
I have recreated the behavior you observe. The Show (e.g Push) segue does indeed work from one viewController embedded in a navigationController to a second viewController embedded in a different navigationController.
Note that when the push happens, the second viewController slides in in the normal push way, and a back button appears that takes you back to the first viewController. This tells you that the second viewController is actually being pushed onto the stack of the first navigationController. So instead of giving you the error message, it is simply ignoring your second navigationController.
When using a navigationController, only the first viewController is imbedded in a navigationController. You don't have to embed subsequent viewControllers in a navigationController, because when you wire up the Push segue from a previous viewController in the navigationController's stack, the Storyboard will recognize that this new viewController is controlled by a navigationController and it will add the navigationBar at the top.
Original Answer:
A Show (e.g. Push) segue is an Adaptive Segue. It chooses the correct segue type based upon the situation.
If your source viewController is in embedded in a Navigation Controller, it does a Push.
If your source viewController is in a SplitViewController without a NavigationController, it does a Replace.
In all other cases, it does a Modal segue.
So, it works because it is actually doing a Modal segue in your case, which works if you aren't using size classes. You will notice that the presented viewController actually slides in from the bottom which is a tell-tale sign of a Modal segue.
You can find information about it here:
Backward Compatibility of Active Segues.

Getting current visible modalViewController from appdelegate

I have a navigation controller which acts as an rootViewController and I have one view controller which is presented modally (not pushed). So my control reaches app delegate while this presented viewController is the one, which is visible. So my question is, how can I get this viewController in appDel? And, No, its not my rootViewController and is not present in navigation stack.
I believe yo may use presentedViewController property of rootViewController. Check this answer for more details: https://stackoverflow.com/a/12684721/1301013

difference between presentViewController and UINavigationController?

Please tell the difference between presentViewController and UiNavigationController? Could I use presentViewController instead of UINavigationController to navigate different views in the app?
Whats the scenario to use either?
presentViewController offers a mechanism to display a so-called modal view controller; i.e., a view controller that will take full control of your UI by being superimposed on top of a presenting controller.
UINavigationController offers a much more flexible mechanism where you can push a new controller, and later pop it, so to go back to the previous one, in a ordered way. Imagine that controllers in a navigation controller will just build a sequence from left to right.
I think that presentViewController is most suitable for use with just one view controller being presented at a time. You can surely use it to stack more view controllers one on top of the other (and thus sort of "mimic" a poor-man's navigation controller), but my bet is you will quickly find something not working as you expected.
Specifically, an example of such limitation is the following: when you dismiss a modal view controller (in order to "close" it), all of your modally presented view controllers (from the same presenting controller) will also be dismissed at once. So you simply will not be able to implement a "go back"/navigation like functionality.
So, it depends on what you are trying to do.
A UINavigationController is a subclass of UIViewController that manages a stack of view controllers and adds a back button etc.
presentViewController is a method of the UIViewController class you use to present a modal view controller.
The UINavigationController maintains a navigation stack for you. You are then able to navigate through hierarchical content.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
If you use UIViewControllers presentViewController method you are basically just replacing the view controller. no navigation stack is maintained for you.
UINavigationController is a class, presentViewController is an instance method of UIViewController (iOS 5 + ), of which UINavigationController is a subclass.
pushViewController is a comparable method to presentViewController. It is an instance method of UINavigationController, for iOS 2 +

ViewController to NavigationController and back

I have one problem for which im not sure how to solve. Currently i have main UIViewController with some buttons. This is the initial view that is created with app. On it, one button calls storyboards segue with style Modal on ViewController which is part of UINavigationController. After that few other viewcontrollers are handled within the UINavigationController via segues and getting back via navigationController:popViewControllerAnimated. What i dont know is how to get back from UINavigationController to first UIViewController. I tried, when I'm on first one on navigationctrl,
[self removeFromParentViewController];
yet that only removes the view but it seems that UINavigationController somehow stays alive as result is black screen. Creating unconnected segue and call it from code would be possibility, but im not sure if that is the proper way. Would that leave navigation controller alive ?
Is there any reason you are using a UIViewController first and THEN a UINavigationController?
Why not change this so that the UINavigationController is the initial view controller and then drive everything from there.
If you want the first view to not have a nav bar then you can hide it easily.
That way you can move around through all views by popping and pushing through the UINavigationController.

Resources