How to push and pop view controllers in UISplitViewController in iOS? - ios

From Apple's Documentation,
When designing your split view interface, it is best to install
primary and secondary view controllers that do not change. A common
technique is to install navigation controllers in both positions and
then push and pop new content as needed.
My app has a UISplitViewController as a root view controller. As per documentation, I created two dummy navigation controllers(say primaryNC & secondaryNC) and placed them as primary & secondary view controllers in UISplitViewController using the setViewControllers: method.
My primary controller is a tab bar controller, and the secondary controller is normal UIViewController.
I can not find how to push/pop view controllers into primary/secondary navigation controllers. Redirecting to any example code would be helpful.
P.S: I am doing this programmatically not using nib/xib. I am using objective c.

Related

Back Navigation from Embedded UISplitViewController Using Single Navigation Bar

I’d like to have split views in several places of my iOS app, none of them as the root view controller. I understand that split views are initially designed to sit at the root of the app and provide the root navigation controller, and that Apple’s guidelines initially did not allow any workarounds. Updated guidelines state
You cannot push a split view controller onto a navigation stack. Although it is possible to install a split view controller as a child in some other container view controllers, doing is not recommended in most cases.
Now the split view pattern would really benefit my app, and I don’t want to reinvent the wheel here, so I gave it a try using a container view, mainly using the following steps:
Create a scene with a regular UIViewController.
Add a UIContainerView covering the entire screen.
Add a UISplitViewController to the storyboard, which creates a split view controller, a navigation controller, a table view controller (for the master view), and a regular view controller (for the detail view).
Create an embed segue from the container view to the split view controller.
This has a few quirks, which I hope to iron out eventually (e.g. initially showing detail view, swiping in the table view from the left on an iPad apparently tries to also back nav on the main navigation), but it basically works. So far, so good.
Now, the problem is that I have two navigation controllers: the main navigation controller at the root of my app and the navigation controller in the embedded split view. This gives me two navigation bars with independent navigation, allowing me to:
navigate back to the root of the split view using the embedded navigation controller
navigate back from the container view in the enclosing navigation controller
Besides two navigation bars not being appealing, I don’t want iPhone users to perform the second directly from the detail view. So my next steps were:
hide the navigation bar in the outer view controller
add a back navigation button to the inner navigation bar to take over the role of the main navigation bar’s back button
Left to do is the implementation for that back button that pops the container's view controller of the main navigation stack. The question is: how can I access the main navigation controller from the embedded view that has its own navigation controller (using Swift)?
Accessing the navigation stack of the parent's (containing view controller's) navigation controller turned out to be straightforward:
#IBAction func backButtonTapped(_ sender: UIBarButtonItem) {
parent?.navigationController?.popViewController(animated: true)
}
I had to face a similar kind of problem while developing my app.
My problem was, I had to display navigation controller and splitviewcontroller on side bar. Again a problem was navigation controller form splitview to navigation controller. Below are the steps which i followed
1) While creating a split view controller, I hided the navigation controller of master and detail and set it to root view, please also keep the reference of your top level navigation controller.
2) I increased the 'y' of splitview.root.window and view to accommodate custom view.
3) I created a custom view with a back button and then handled the transition with animation.
Please let me know if you want code snippets. I would have shared it now. But i have to search for it.

Can I have a SplitViewController inside a TabBarViewController(iOS 9.0 +)?

I have an app with UITabBarViewController as rootviewcontroller. On some tab item, I want to have a SplitViewController inside a UITabbarViewController.
So here my UISplitViewController will become a childViewController for TabbarVC.
Will this be allowed? Are there any Apple guidelines suggesting not to do this?
As I see, they are suggesting to put SplitVC as RootVC. But many applications have already done what we are doing now.
Answers here might help Apple recommends UISplitViewController should always be the rootviewcontroller
I had nearly same scenario of creating a UISplitViewController inside a view controller. So I created my own custom SplitViewController
Here is the note from apple
You cannot push a split view controller onto a navigation stack. Although it is possible to install a split view controller as a child in some other container view controllers, doing is not recommended in most cases. Split view controllers are normally installed at the root of your app’s window.
Apple HIG recommends to have tab bar as the root or split view controller as root. But I still achieved this by putting in a container for one of the tab bar's child view controller. And as a result, you can load split view controller into the container view of any view controller, irrespective of whether its tab bar or a normal view controller.

Multiple Push Segues to One View Controller in Storyboard

I have an application in Xcode 4.6 that uses storyboards. The root view controller is embedded in a navigation controller, and all view controllers in the application are accessed via push segues via the navigation controller.
I ran into a complication when I wanted to have one particular view controller (called photos) accessed via a push segue by two different view controllers. I ended up with what appeared to be a navigation controller inside a navigation controller in the photos controller after I added the second segue. The goal is to just have (in photos) one navigation bar with a dismiss button that (when pressed) pops back to whichever of the two view controllers presented the photos view controller. I am somewhat new to iOS and I am not sure of the best way to accomplish this or how to generally handle this situation.
Here is a picture of my storyboard for reference:
You should really do it programmatically using SotyboardID. It's only a few lines of code in each ViewControler.

IPad Split View Implement in Another View

I am creating a iPad App and it has several views to load data,but for one view i need to add split view. I dont need split views in other views. They are just detail pages. I search Through the net and found lots of tutorials based on iPad split view. But the problem is they all are creating a project as Split view project or they create a window base app and add slipt view to the delegate. I dont need to do that, I need to implement this split view only for one view. Is There any way to overcome this problem?
You can add the split view inside a Navigation Controller.
Even if the Split View is a container view controller and Apple recommends in the documentation that all containers should not be embedded in other containers, adding a split view inside a navigation controller works correctly and I never noticed any side effect in doing it.
Basically what you should do is:
- in the app delegate create a UINavigationController and use it as root view of your application window
- hide the navigation controller navigation bar if you don't want to see it (showing a split view with a main navbar on top is not nice looking...)
- then add your view controllers inside the navigation bar.
Example: imagine you have this application views sequence:
FIRST VIEW (full view = detail page)
SECOND VIEW (split view)
THIRD VIEW (full = detail page)
So you can represent FIRST and THIRD as standard view controllers (full screen), while SECOND will be a split view. Your app will be initialized by creating the main navigation controller, adding FIRST on it as top controller and using the main navigation controller as window's root view.
Than use the navigation controller push, pop methods to switch between these views or change the navigation controller "viewControllers" array directly if you don't want the recommended push/pop methods.
If you need to add special behavior to the navigation controller based on the type of view on top, just register your app delegate as navigation controller delegate (or a "main controller" object dedicated to this if you don't want to complicate your app delegate).
I am not 100% sure, but it seems to me that you can't use a SplitView just somewhere in your view hierarchy.
The Apple intended way is to use the SplitViewController as the top level controller. The left side of it can include a drill down mechanism with a navigation controller so you are ably to drill down hierarchies and the right side will present details for the item you select on the left side.
If you need a view with some kind of split mechanism in it, you probably have to code it yourself. Or even better: find some other mechanism you can use in your UI.
How are you switching your view hierarchies now? Maybe you could integrate your existing UI into a SplitViewController?

Objective-C - Understanding view controllers

I understand that view controllers help control multiple views in an application, but I have trouble understanding when to use them.
If I have an application with a main page, several views with a "hierarchy" structure, and an about page not connected with the hierarchy, what files should my application have? An appdelegate, navigation controller and view controller? More than one view controller? Just a navigation controller?
Also, should they all be contained in one .xib file, or multiple .xib files?
Any help would be greatly appreciated.
Thanks.
A good habit is to have a UIViewController for each page you want to show. If I get the structure of your app you should have a main page (with many other UIViews inside it) and another page (about page). If that's true I suggest two UIViewControllers.
The UINavigationController is a subclass of UIViewController that lets you "navigate" among the pages. It's not strictly necessary but suggested (you can also implement your self a custom navigation system, but it's easier to exploit the one Apple offers you). Another navigation system is the one based on UITabBarController, if you want to take a look.
Assuming I get the structure of your app you should need two .xib file, one for each page you have.
The app delegate is conceptually different from a view controller, you'll have just a single app delegate, automatically created by Xcode (you can, of course, modify it to fit your needs).
Each "screenful of content" (Apple uses this term) should be handled by it's UIViewController or more likely a subclass of it. The point of view controller is to handle view appearing or disappearing (going on/offscreen), device rotation, memory management, navigating to other view controllers and so on. If you are creating your UI with IB, then each of those view controllers would most likely have it's own .xib file.
Each view controller has one view (it's view property) that acts as main view for each "screenful of content" to which you then add your subviews.
UINavigationController and UITabBarcontroller are there to help you control the hierarchy of your app. They only act as containers for other view controllers and don't contain any UI except navigation bar or tab bar. Using tab bar controller you can have multiple view controllers which act exactly like browser tabs. Using navigation controller you can have a stack-like navigation where new view controllers are pushed from right to left and are popped from left to right when user goes back to previous view controller. You can even have a view controller inside navigation controller inside a tab bar controller.
If you don't want to use tab bar or navigation controller, you can navigate through your view controllers by presenting them modally using presentModalViewController:animated: and dismissing by dismissModalViewControllerAnimated:. If you send YES for animated parameter of these methods, you will get an animation specified by the modalTransitionStyle property of view controller being presented or dismissed. Possible animations are slide in from bottom (default), horizontal flip of entire screen, fade in/out and half-page curl.
There are also some Apple-provided subclasses of UIViewController that help you setup your UI quicker like UITableViewController which is basically a view controller that contains a table as it's main view and conforms to 'UITableViewdataSourceanddelegate` protocols which are required to define how each cell looks and what it contains.
On iPad there is one additional container controller UISplitViewController and one additional way to present new view controllers using UIPopover.

Resources