How do I handle a view controller in my Storyboard with two distinct layouts? - ios

I have a UIViewController in my Storyboard that can have one of two layouts, depending on which setting the user chose.
One uses a UITableView to display the information, while the other uses UICollectionView.
In code, I'd simply set up the view controller depending on the setting, but I don't see how I would do this with a Storyboard. How do I handle the multiple layouts in a Storyboard environment? (Worth mentioning this view controller is embedded in a navigation controller.)

This situation is no different than any time you have to make a choice in an app as to which controller should be shown next. Have two different navigation controllers (with storyboard identifiers) set up in the storyboard, one whose root view controller has the table view, and the other with the collection view. After the user makes a choice, instantiate the correct navigation controller, and segue to it, or make it the window's root view controller.

Related

Storyboards and UITabBarControllers

I'm using Storyboards for the first time. It's mostly going okay, but one situation is very unclear:
I'm using a Tab Bar Controller as my Initial View Controller. I have three tabs, and they're each an instance of the same view controller class, the only difference being that I want to pass in a different array to each instance, to display different data.
My thought was I could use prepareForSegue: in the UITabBarController instance to pass the proper array to each destination view controller…but maybe UITabBarController isn't using segues to display each view controller in a tab, because there's no way in IB to specify a Storyboard ID for the "segue" to the tab contents. (If I select the segue that connects the Tab Controller to the child Controller, IB just says "Not Applicable" in the customizer area.)
So my question is: how can I handle this situation in IB?
UITabBarController uses segues, but it is a special kind of segues. Select a UITabBarController in the IB, and open the Connections inspector in the Utilities area. You'll see that there are Presenting Segues in the bottom (those are handled by prepareForSegue) and Triggered Segues, which include viewControllers segues. Those are the segues to tabs inside a tab bar. They are not really segues, they are more like references.
In order to use one class for three different view controllers as tabs in IB, you should add three empty (or not) view controllers as tabs and specify their class using the Identity Inspector in the Utilities area. The class can be the same for all three.

How to conditionally set root view controller for a Navigation Controller

I have a navigation controller which should have a different root depending on the state of my App.
How can i model this within Interface Builder? I've dragged out a UINavigationController to my Storyboard. Now I need to make the connections to the two view controllers.
Sadly I can only set one as root view controller. Do i need to subclass the Navigation Controller and based on the state reset the root view controller?
What is the best practise for this kind of problem? It would be nice to visualize this relationship within Interface Builder.
Thanks in advance for any help.
As it is the rootViewController you want to change conditionally, you could instead have two different navigationControllers, each with the one of the two different viewControllers as its rootViewController.
You could then present the appropriate navigationController based on your condition.
Have two segues (one to viewcontrollerA and the other to viewcontrollerB). The your Navigation Controller would determine the App state and call performSegue to move the user to the correct view controller.

How to point two UINavigationControllers to one view controller using storyboards?

I am attempting to connect two UINavigationControllers, representing different tabs in a tab bar application, towards a single UICollectionViewController. The collection view controller will be populated by different data based on which navigation controller is the parent. When both navigation controllers are connected, navigating to the second tab displays a black screen and the viewWillAppear() code in the controller for the collection view does not fire. When navigating to the first tab, everything fires and is displayed correctly with data populated.
The storyboard setup looks like this:
The navigation controllers are connected to the collection view controller as seen here:
If I disconnect either one of the two navigation controller connections, the remaining connection to the collection view works and collection items are displayed as expected.
Is this the correct way to reuse the collection view? Is there something missing from how I am connecting the two navigation controllers with segues to the single UICollectionView?
I see this is almost a year old, so I'm not sure if you found an answer or not, but I thought I'd help answer if needed. Without knowing too much of your project, can I ask why you want a tabBarController to point both of its view controllers to the same one? Makes me wonder why tabBarController is necessary.
Setting up a test project, I witnessed the same you did. The only thing I can think of is that when a view controller is instantiated via the Storyboard, it creates an instance of it and is stored in the tabBarController's viewControllers[i] property, which the other tab may not have access to in the hierarchy. It would be best to just copy the view controller object from the Storyboard and paste it onto another area of the storyboard, and have the tabBarController instantiate a new instance of the same view controller object. That way, in your viewDidLoad method, you can tell what the selectedIndex is, and know how to load data, alter interface, etc. Copying/pasting the Storyboard view controller should keep intact any outlets/actions you've set up.
Hope that helps...

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