views:

530

answers:

4

Can anyone explain why it's not possible to create your own view controller hierarchies using UIKit on the iPhone?

Let me explain: when creating applications using a complex view hierarchy and navigation logic, it's a good idea to have certain views controlled by a dedicated view controller. These controllers can have their own subcontrollers, and so on. All standard stuff really.

So why is the parentViewController property readonly? It's used by UINavigationController and UITabBarController, and many other properties rely on it (for example the navigationController property).

I've seen many people telling us to create our own property for managing view controller hierarchies, but that's a little silly when Apple's own framework uses its own private "you can't touch it" hierarchy model.

+2  A: 

Your question is more of a rant than a question.

parentViewController is only really used in modal view controller presentations, as indicated by being in the "Presenting Modal Views" section of the documentation. The navigation and tab bar controllers each have their own property (navigationController and tabBarController respectively.) for accessing them as parent view controllers, so what's the big deal in adding your own?

If you want custom behavior, you'll need to add custom code.

Ben S
That's not entirely true. You can set the parentViewController property by calling [controller setParentViewController:] (you get a warning though, but it works). When there's a UINavigationController several levels up the hierarchy, the **navigationController** property will return the correct controller instance. So it's not only used by a model view controller, but by every built-in view controller that uses some kind of navigation.
Philippe Leybaert
+2  A: 

Readonly properties are usually properties that an instance must have set all the time to avoid serious problems.

In this case of a navigable hierarchy, child controllers must be able to have access to the parent controller at all times. (This is trait defines the actual navigation hierarchy i.e. you can back out of subviews.) If the property is readwrite it might not be set,might not be set correctly or might suddenly change all of which would orphan the controller. That is unacceptable in the API upon which the entire platform depends.

Why risk making the API more fragile just to handle a rare design case? It's easy enough to roll your own for the rare circumstance in which you want a flexible hierarchy.

TechZen
Is having your own view controller hierarchy "a rare case"?
Philippe Leybaert
Yes, very much a rare case. I've not found a need for it yet in several very complex apps.
Kendall Helmstetter Gelner
I think it is a rare case that the API classes cannot handle. I've yet to run into one in either my code or the code of others I have examined. If you keep requiring them, perhaps you've got a glitch in your understanding of the API design.
TechZen
A: 

Totally agree with Ben. Try asking the opposite question. Why did Apple create a tabBarController and navigationController property in a UIViewController. This could've easily, well not easily, be accomplished with some hacking around of the parentViewController property. Something like this to find the tab view controller would be common across all apps:

UIViewController *current = ...;
while([current parentViewController] != nil) {
    current = [current parentViewController];
    if([current isKindOfClass:[UITabViewController class]]) {
        // do something
    }
}

Yes, it probably goes against intuition as a navigation, or a tab bar controller, is most likely also a parent view controller.

There is no harm in using the parentViewController property actually. To get past the warning, checkout this thread.

But once you expose any data/behavior in the hierarchy's parent view controller, these isKindOfClass checks would become far too common.

Anurag
A: 

Explain what you mean by "complex", that you cannot do with the system as it exists.

Controllers can have subcontrollers... you can either compose subcontrollers/views and delegate work, or have complex inheritance hierarchies of controllers to manage behavior.

I would love to see a concrete example of what it is you think you cannot do.

Kendall Helmstetter Gelner
Complex is probably not the right word. What if you want to create a custom view controller which has navigation similar to the tab bar controller? You'd need to have a number of subcontrollers (just like UITabBarController has), but you're not allowed to use the built-in parentViewController property. You'd have to create your own pointer to the parent (I can't believe I'm the only one who thinks this is plain silly).
Philippe Leybaert