2

I am building a UIViewController with a XIB. In this XIB, I have placeholders (UIView objects in the XIB) in which I place other views, from other view controllers. (By the way, I could also add these views directly, without placeholders)

I am not buiding a container view controller: I mean it's not a UINavigationController. It's a just a "usual" view controller. Imagine for example that I have a small subview in my view for a "Facebook" logo and a counter. This "facebook view" is attached to another view controller that is called when the "Facebook view" is touched. So, the "Facebook controller" definitely needs to be a @property of my "main" view controller.

In this situation, should I really use addChildViewController: and all the mechanism? Or no?

Thanks!

Colas
  • 3,473
  • 4
  • 29
  • 68

3 Answers3

4

You should not be using a UIViewController merely to "fish" into a .xib file for you to obtain the view. If that's all you want it for, don't do that. Just load the nib and pull out the view, directly:

NSArray* objects = [[UINib nibWithNibName: @"MyNib" bundle: nil]
            instantiateWithOwner:nil options:nil];
UIView* v = (UIView*)[objects firstObject];

But if you are using a UIViewController in conjunction with this .xib file for some other reason, e.g. to keep it alive so that a button inside the .xib can send messages to this UIViewController, then absolutely you must make a proper parent-child relationship, as I describe in my book: http://www.apeth.com/iOSBook/ch19.html#_container_view_controllers

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • I was hoping we'd get to this aspect of your previous question! – matt Apr 30 '15 at 19:14
  • Yes, but imagine I need the view but also the controller of `SubViewController`? For instance, when a user touch a button in it, the controller does some action. In that case, do I need, in addition, to add `SubViewController` as a child of `MainViewController`? – Colas Apr 30 '15 at 19:31
  • Yes. There's no other correct way to keep SubViewController alive and to have its view inside your MainViewController's view. As you've been told, that's what a parent-child relationship _is_, and there is only one correct way to do that. — I modified my answer to emphasize that point. – matt Apr 30 '15 at 20:09
  • It sounds so strange to me... I can't believe it! Really. For me, parent-child relationships are only for `UINavigationController` and so on. For example, on `OSX` there is no such parent-child relationship. – Colas Apr 30 '15 at 20:12
  • Well, that's because view controllers were invented for iOS - they were then read backwards onto OS X, so support is not fully integrated in the same way. – matt Apr 30 '15 at 20:14
  • Are you kidding? `UIViewController` is one of oldest class of cocoa! – Colas Apr 30 '15 at 20:15
  • You might be thinking of NSWindowController, which is totally different in every way. Nothing on OS X starts with UI... UIViewController is part of UIKit; it was invented purely for iOS, to cope with the tiny screen and only one window. You might want to read my whole chapter on this topic: http://www.apeth.com/iOSBook/ch19.html – matt Apr 30 '15 at 20:35
  • OK, `NSViewController` is one of oldest class of cocoa, sorry ;-) – Colas Apr 30 '15 at 20:36
  • Well whatever. None of that changes anything about either of my answers. – matt Apr 30 '15 at 20:38
  • Just when you said "that's because view controllers were invented for iOS", that's false. You meant `UINavigationController`, `TabBar`, etc. which (IMHO) are the ones that need the parent/child mechanism. I admit what I say is entirely based on my understanding of what Apple does and not at all on my knowledge (equal to 0) or my experience (equal to 0 also). Thanks for your words and your knowledge! I will come back to this topics. I might write to cocoadev. – Colas Apr 30 '15 at 20:41
  • iOS SDK (CocoaTouch) is strongly inspired from OS X SDK (Cocoa). but CocoaTouch is far more recent and more evolved than Cocoa, especially releating to structuring interface and putting views into views. it is clearly specified to not do it in Cocoa (OSX) because the order of drawing is not assured. You have to go one level down in structuration and revert to NSLayer. – Nicolas Buquet May 01 '15 at 12:05
  • @matt I had good replies from cocoadev. I will update this post. Your were right matt. – Colas May 04 '15 at 12:22
2

Yes, you should. By doing so, the containing view controller sends proper view controller lifecycle events to the child view controllers.

You say you aren't building a container view controller but you are. Adding the view of another view controller to another view controller is the definition of a container view controller.

See the "Implementing a Container View Controller" section of the docs for UIViewController on the proper sequence of method calls you should make. It's more than just calling addChildViewController.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
0

You can instantiate your insider ViewController, and just add its view (myInsiderViewController.view) to your main viewController:

[mainViewController.view addSubView:myInsiderViewController.view];
Nicolas Buquet
  • 3,880
  • 28
  • 28
  • So I don't need, in addition, to add `myInsiderViewController` as a child of `mainViewController ` ? – Colas Apr 30 '15 at 19:28
  • No you don't: your myInsiderViewController will be released, but as you added its view to mainViewController.view, its view will not be released beczuse it is retained (owned) by mainController.view. – Nicolas Buquet May 01 '15 at 11:18
  • But I need to keep a (strong) reference to the controller. I have a strong reference called `myFacebookController`. In addition to that, do I need to use the parent/child mechanism. That is my question (see edits of my questions). – Colas May 01 '15 at 11:25
  • Keep a strong reference (a retain) on it by storing it in a property (or an ivar of your object), so you can use it later, but you don't need to add your myFacebookController to your mainViewController. But if you need to use parent/child mechanism on the ViewControllers, then add it as a child ViewController. – Nicolas Buquet May 01 '15 at 12:03