UISplitViewController: Why should I never present it inside of a navigation or tab bar interface? - ipad

From Apple: "You should never present a split view inside of a navigation or tab bar interface."
They don't say why, and they only say "should" not. What would happen if I do it? I can imagine so many good use cases where I would want to!

Your application may crash. The UISplitViewController was designed to be the root view controller in the VC stack.
SO Question:
Split view controller must be root view controller
Also, as stated in the Class Reference:
The split view controller has no
significant interface of its own. Its
job is to coordinate the presentation
of its two child view controllers and
to manage the transitions among
different orientations.

I wrote this question which is related. As Evan notes, usually you just have to roll with Apple's damands. I tried to work around their restrictions; it failed horribly. UISplitViewController is extremely fragile if you do anything Apple don't want you to.

Related

Navigation Controllers with the same root view

So suppose you need some functionality that requires next storyboard. For example you need to upload different content to view depending on what tab is clicked.
But the problem comes out when you try to use this storyboard. When you switch tabs you getting this behaviour.
But in first tab everything fine. So looks like it doesn't load view second time. Can somebody explain or give a link to the behaviour of navigation controller in this case, because I can't find anything useful in reference. Or how should I correct this behaviour in IB or programatically? Thanks.
a simple work-around is to put a "fake-viewcontroller" as root for the second navigation. On this "fake" controller execute in viewDidLoad a [self performSegueWithIdentifier: #"goToTheControllerHereWeGo" sender: self];
So, as I mentioned in my comment I do think this is a bug but we'll see how Apple responds. But yeah, segues have no love for view controllers that are the root view controllers of multiple navigation controllers. There are a number of workarounds depending on the context under which it comes up.
Best workaround : Share the navigation controllers, not their root view controllers
So for the simple example given above you could do this and everything would be fine:
Other workaround : This one is more applicable to complex storyboards that may have different custom navigation controllers so that sharing the nav controller isn't possible. One hilarious aspect of this issue is that when a view controller has two parent nav controllers in the storyboard, you won't know until runtime which one gets it! And further, on different runs they can switch :P (another reason I think this is a bug).
Sooooo from within prepareForSegue you can check if your navigation controller got unpacked with a rootViewController and, if it didn't, force it in there yourself:
UINavigationController* nc = segue.destinationViewController ;
if (nc.viewControllers.count == 0) {
nc.viewControllers = #[[self.storyboard instantiateViewControllerWithIdentifier:#"MyDetailVC"]];
}
Just provide more explanation beside the comments 'You cannot make a UIViewController as the root view controller of two different Navigation controller'. Suppose you can do so, then the view of the controller will be child view of the two navigation controller's view. It cannot happen as "it" cannot be a child of A but simultaneously a child of B.
On what condition will the tabview items switch , also trigger one of the two separate view controllers? what is the logic? when is it implemented? and no matter whatever the logic maybe, why does a single view controller (let us assume it is being filled up with different data according to the root) has 2 separate roots? we cannot add anything separately from the navigation controller itself,
Navigation controller is the flow that sets the storyboard in motion, but putting a VC as a subview of two different NC just has no point.
Think it of like this,
No additional information is provided by the Navigation controller itself, it just sets things in motion. So why would you want to put a VC as the child of 2root NC.
More easily think it as multiple inheritance, in objc, java its not possible because of the
Diamond problem. look it up and i hope it helps u understand

Good way in iOS to have a view outside a UITabViewController

I'm just getting back into iOS development after a year or so away and am looking for a way to have a single view above or below a UITabViewController view. The idea is to have one ad view that is used throughout the app instead of one on each tab. The constant reinitializing of the ad view seems like it would be a lot of overhead so having one persist throughout would seem to be more effective.
I've searched for this but not found much of anything so even a useful link would be appreciated.
Thanks in advance,
Jason
I see several approaches here:
Since you are setting up your view hierarchy in your application's delegate, I'd suggest creating a separate UIViewController and managing it from your app delegate. That way you can show/hide it in the main UIWindow, without having to do much work.
You can subclass UITabBarController and show the ad in the visible view controller. This is more work, but your app architecture is arguably cleaner, because your app delegate doesn't get cluttered with ad-related code.
Another option is to look into a UIViewController category, where you can manage add related code. Not necessarily the cleanest, but it keeps the ads out of both your app delegate, and your tab bar controller. (You'd add the ad view as a category property via runtime level calls and associate objects, but that gets messy.)
I'd probably go with the first approach if it were me, but I could argue for either of the other two approaches, since an ad view doesn't really necessitate it's own view controller.
How about create a parent view controller and each view controller inherits from that parent view controller? Parent view controller has a ad view or table view, so every child view controller will has those two view as well.
Okay, after spending some time trying to create and manage a customer view controller for this I stumbled on the Container View Controller capability Apple added in iOS 5. I have no need to support iOS 4 or earlier so this works good for me. There's a good description of it here (unfortunately the author never wrote part 2 with a tutorial):
Container View Controller description
And a decent tutorial is available here:
Container View Controller tutorial
Between the two of these I was able to create a good setup with an AdViewController and BodyViewController (TabBarController) contained in a Container View Controller. This gives me all the capabilities I need (at least so far).

Segue always loads new instance of view

I'm executing a segue like so;
[self performSegueWithIdentifier:#"showSecondView" sender:self];
But the behavior is that it will always "load" the new view rather than show the existing view if it was already loaded.
My question is, how can I keep a view in memory once I've loaded it, so that future segue calls will simply "show" the existing view?
Thanks
EDIT:
Here is my user interface design. It's essentially a custom side tabbar view controller with a UIView (the big gray block) where all of the subviews are placed.
The short answer is that iOS isn't well suited for that, but you might be able to do so. It depends.
The question is how is that view's controller represented in the view controller hierarchy. The standard options are pushViewController (a push segue) or presentViewController (a modal segue). You might be able to do a custom segue that takes advantage of view controller containment (see WWDC 2011 session 102), but I'd be surprised if that would be something you'd want to pursue. Usually when you hear people talking about the frustration of creating new views is a result of their wanting to return to some main view, but neglecting to popToRootViewController and instead having a segue back to that root scene.
A wholly theoretical (and probably impractical) answer that might come up is to use a singleton and do some slight of hand to transition views, but after watching WWDC 2011 session 102 on view controller containment in which they belabor the importance of keeping one's view hierarchy synchronized with the view controller hierarchy, so I don't think that makes sense.
I might be able to make a more meaningful suggestion if I understood your desired user interface. For 99% of apps, they are geared around pushing/popping views, presenting/dismissing modal views, or using some container (e.g. a tab bar container or some custom container) for jumping between sibling views. What is your user interface flow?

Using a View Controller managing two other View Controllers

I have a offlineMapVC and a onlineMapVC for my application to support both online maps (using MapKit and Google Maps) and offline maps (using Route-Me).
I made my own mapVC to manage the switching of these mapVCs and be able to use the view controller as one separate view controller. Well I've done this by making the offlineMapVC and the onlineMapVC instance variables of the new mapVC witch I now use all over my application.
First off all things seem to work but. However while using this approach for a longer time I ran into some problems due my using of View Controllers in a hierarchy. I read this is the wrong way to go. What is the right way to manage the switching between two view controllers? My question seems fairly simple but I couldn't find a decent solution.
I put view controllers in view controllers, myself, and I have seen much better programmers than me doing the same thing. (See Rob Napier "iOS 5 Programming - Pushing the Limits". He mentions it frequently.) As long as you don't have more than one view controller directly controlling the same views and subviews, you should be okay with it.
Since Jonah Williams wrote that article, I think iOS 5 formalized the use of view controller hierarchy with custom content view controllers. You might consider your mapVC to be a custom content view controller and implement onlineMapVC and offlineMapVC as child view controllers.
(Apple documentation links tend to change frequenctly, so Google "Custom Content View Controller" for the documentation.)
If you can give some more context to what you mean by "switching between two view controllers" that would help answer your question. Generally, I have more than one view controller active at the same time. I don't switch between them. (I use navigation and tab bar controllers in the same applicaiton, but I assume you are aware of how those work and you're asking a different question. It's just not clear what the detials are in your case.)

iPad Navigation Patterns

I've been working on an iPad application that has about 15 view controllers. Some of the view controllers are full screen, others are embedded inside the other view controllers (think split view controller).
On the iPhone navigation is very straight forward. Even if you have a ton of view controllers, you are using one of Apple's root view controllers (tab or navigation). The navigation is handled by the root view controllers and you are pretty much free to focus on your views.
On the ipad the split view and tab view controllers are not always useful, and for the app I'm working on they do not cut it. I have created separate navigation controller objects to handle hiding/show view controllers based on notifications that get posted when the user performs actions.
Anyone else have experience with solving the navigation problem on the iPad?
have you checked out MGSplitViewController by Matt Gemmell?
http://mattgemmell.com/2010/08/03/mgsplitviewcontroller-updated
I'm not claiming it'll solve all your navigation problems, but it's an interesting idea and may help you in finding more/better ways of handling view controllers.
With iOS 5 Apple has added the concept of Container View Controllers. This makes adding and removing children easy, allowing their methods for rotation/appear/disappear to be called automagically. Cool stuff!
Also, be careful using multiple view controllers for views which don't fill the full screen. Apple's documentation explicitly states that you shouldn't use view controllers for partial-screen views:
Note: You should not use view controllers to manage views that fill only a part of their window—that is, only part of the area defined by the application content rectangle. If you want to have an interface composed of several smaller views, embed them all in a single root view and manage that view with your view controller.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Although some things might work when you have multiple view controllers managing different sub-views, other things won't work. For example, only one of your view controllers will be informed when the device is rotated. Likewise, not all your view controllers will be sent 'viewWillAppear' 'viewDidUnload' etc messages that you might expect.

Resources