4

So, create a custom NSViewController subclass with xib/nib. Then in the app's main nib, add an NSViewController object from the object library, set the class to the custom view controller class. Create IBOutlet in the app delegate for the custom view controller.

Add an NSView object to the window. Set the view controller's view to the NSView in the window.

When I build & run, the view is the generic view in the main nib, not the one from the view controller's nib...

What else is needed to get this process to work as I think it should? I would think this should populate the view (and any subviews) from the custom view controller's nib.

I know how to do this in code, but it sure seems like boiler plate. (especially with the addition of auto layout constraints.)

Please tell me I am missing something stupidly obvious.

Hussain Shabbir
  • 14,801
  • 5
  • 40
  • 56
uchuugaka
  • 12,679
  • 6
  • 37
  • 55

1 Answers1

6

When you connect the view outlet of the NSViewController to the empty generic container view, it's replacing the actual view loaded from the NIB with the empty view at runtime.

Unfortunately there's no way to do what you're asking purely by using Interface Builder and outlets. The easiest alternative method:

Add the NSViewController object to the main XIB file and set the Nib Name and Nib Bundle in the Attributes inspector, but don't set the view outlet to the empty container view.

Add properties to your application delegate (or other controller class exposed in the XIB) to create IBOutlets to the view controller and container view. Example:

@property (nonatomic, strong) IBOutlet NSViewController *viewController; // view controller in XIB
@property (nonatomic, weak) IBOutlet NSView *containerView;

Connect these outlets in the XIB to the view controller and container view. Now, at runtime, add the view controller's view as a subview of the container view:

NSView *realView = self.viewController.view;
realView.frame = self.containerView.bounds;
// Also configure autoresizing behaviour for realView using either autoresizing masks 
// or layout constraints so that realView resizes with its parent container
[self.containerView addSubview:realView];
indragie
  • 18,002
  • 16
  • 95
  • 164
  • This is what I was afraid of. But it seems there must be a way. If view-based table views and NSCollectionView can do it. I guess I just don't see a lot of usefulness in the view controller proxy in a xib/nib if it is only good for hooking up bindings and stuff. I will hold out a bit for additional responses but I fear you're correct. Thanks! – uchuugaka Jan 06 '14 at 05:59
  • I believe this is right. NSViewController is a (relatively) new class and it's not quite as cool as UIViewController. In newer APIs (like NSPopover) you can use it the way you'd imagine, but for just setting up a view in a window you've got to write some code, I think. – Wil Shipley Jan 07 '14 at 11:00
  • Mr. Shipley has been suddenly active and your blog alone carries a lot of weight (not to mention your long history) ... well, I will hold the fort until maybe we get some additional heavy weights :) I'm really hoping somebody knows some magic, unless there is magic coming in 10.10 ... I am aware of how much UIViewController and UIKit have had the fortune of doing things awesomely from the ground up with a clean slate. – uchuugaka Jan 07 '14 at 13:43
  • Is this still true (i.e. the inability to hook up view-controllers to views in IB) in Yosmite (10.10)? There have been massive changes to NSViewController apparently. – Daniel Farrell Aug 09 '14 at 05:29
  • Thank you for this answer. This just really helped me out and your explanation was very clear and to the point. Much appreciated. – eww Mar 29 '17 at 01:01