简体   繁体   中英

Is it advisable to add a UIViewController's view to another UIViewController's view?

Is it advisable to add a UIViewController 's view to another UIViewController 's view ?

Please explain why it is a good practice or a bad practice.

Apple and thus most people following Apple's guidelines will tell you it's bad practice and that Apple added ViewController containment (childViewControllers) for that reason. Unfortunately, most people blindly follow that and won't tell you why it is bad practice. And I'm glad that you do ask that.

The truth is, in a model-view-controller architecture, views should be reuseable regardless of the content they contain, thus the view and the object controlling the view's content should not be the same. Which is exactly what a UIViewController does yet prior to iOS5 Apple discouraged you to use them in multiples while it's a very logical thing to do. Ofcourse this was confusing, many people ignored the guidelines and did it anyway, myself included, apps worked fine and passed app store validation which caused even more confusion. The result is that to this day people still ask questions about this even more than a year after Apple caved and gave us custom container ViewControllers. I've seen people respond to this question often with complex answers as far as recreating UIViewController as a class that inherits from NSObject for very simple issues. Just because Apple discourages using UIViewControllers and without even knowing why.

Since adding a ViewController's view as a subview will often work perfectly and ViewController containment is not available in iOS4 which many still support, too many people don't bother using ViewController containment. It is the cleaner solution and when you feel like using ViewControllers in ViewControllers, you should use it when possible. If not, in most situations you should be able to simply add a ViewController's view as a subview, you just have to know in which situations.

Here's what you can expect if you just add a ViewController's view to another view:

  • View callback methods are not guaranteed to get called. Methods like viewWillAppear, viewDidAppear, viewWillDisappear and viewDidDisappear may or may not get called. It will largely depend on the OS version, in iOS4 they won't ever get called, in iOS5 and above they'll mostly get called. So you can't override these methods because you can't rely on them, you have no control over when, if or how many times they'll get called.
  • The only view callback method that will always get called correctly is viewDidLoad.
  • Rotation callbacks won't get called. Depending on your situation this may be a big deal or not matter at all. If the view's autoresizingmask is enough to reposition and rescale it then you're fine. If not, you can always do a custom implementation when the superview's ViewController's rotation callbacks get called.
  • You have to keep a reference to the ViewController yourself, otherwise it'll get released immediately while its view will still be retained by its superview.

I definitely wouldn't encourage it but I don't discourage it either. It's situational and if you don't have to support iOS4 anymore then you can mostly avoid it. But if you keep the above list in mind then it won't cause any harm either and your app will work fine.

Sometimes it's ok, and sometimes it's not. It's hard to give a better answer than that without showing some diagrams and explaining the relationship between the view controller hierarchy and the view hierarchy.

Fortunately, Apple has already done that. Watch the “Implementing UIViewController Containment” video from WWDC 2011 for a detailed explanation of when it's ok and when it's not.

This is actually a common situation with complex view hierarchies. Since iOS 5, UIViewController enables you to add a child view controller. When you are adding the child controller, you are also adding the child's view into the controller's view.

On the other hand, you should never add a view controller's view to another view controller without adding it as the child view controller.

However, don't abuse it. You should do it when

  • you are implementing a container for a set of controllers (something like your own UINavigationController or UISplitViewController )
  • the child controller is independent. If the child controllers constantly call methods on its parent and viceversa, it would be a better idea to implement the functionality into one controller.

You might get away with it but there is probably a better way. It seems reasonable to think that both will attempt to manipulate the view. My answer is no.

What are you trying to accomplish?

Of course you can add UIViewController's view to another UiViewController's view at least as a class variable. But I can't understand the final goal of this solution. I think it is a bad practice because of the app interface complexity is increasing.

Usually in Model-View-Controller architecture, we can reuse views.

But for the UIViewController, it may be not be always good idea. It might make the project architecture complex because as per Apple documentation views are tightly bound to view-controller, so it may not be easily manageable.

From UIViewController reference: View controllers are tightly bound to the views they manage and take part in the responder chain used to handle events. View controllers are descendants of the UIResponder class and are inserted into the responder chain between the managed root view and its superview, which typically belongs to a different view controller. If the view controller's view does not handle an event, the view controller has the option of handling the event or it can pass the event to the superview.

But, I think we can reuse a view if there is minor difference in the UI for the two different controllers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM