Simple NSViewController Sample Projects

Hello!!

Thanks for all of the feedback on the XS-Controllers design that Jonathan and I posted. We’re going to be making some changes to the design based on feedback, bug reports and the experience we’ve had using it ourselves over the past few months.

First, I want to take a few steps back and offer a couple of example projects that use NSViewController – straight out of the box - in a non-document based application. I hope these will be more useful for people who are just starting out with view controllers. The projects do the following:

  • Create a view controller with a nib file
  • Add several view controllers’ views to the window’s view hierarchy
  • Switching between two view controllers and their views
  • Patch a single view controller into the Responder Chain
  • There’s also a good sample project available on Apple’s site. I recommend checking it out.

    Simple View Controller Xcode Projects

    Simple View Controller - Adding Views to the View Hierarchy

    XcodeProjectIcon.pngDownload SimpleViewControllerPart1.zip

    A window controller creates two view controllers and
    adds their views to the window’s view hierarchy. The window controller keeps references to the view controllers as instance variables. They are not added to the responder chain.

    Simple View Controller 2 - Switching View Controllers

    XcodeProjectIcon.pngDownload SimpleViewControllerPart2.zip

    This project extends the previous project so that the DetailViewController manages the switching between two other view controllers and adding their views to its “contentView”. This gives you tab-like behavior with the addition of view controller switching instead of just view switching.

    The DetailViewController is patched into the responder chain when it is created, after its view is added to the window, so that it can handle the View menu actions for switching the views.

    Note on the Responder Chain:

    If you take a look at the sample code, you’ll notice that I added the DetailViewController to the responder chain after the window controller. This follows Jonathan’s and my design for the XSViewControllers. Many people have asked why we didn’t add the XSViewControllers into the responder chain after their associated views instead. There a couple of reasons for this:

  • A view controller can’t control when its view is added and removed from the view hierarchy, so in a design like ours, there is no reliable way to patch the chain in this way without subclassing and extending NSView to be aware of its view controllers. This is a more intrusive design, in my opinion.
  • There is a significant behavior difference between the two approaches. Action messages take a specific route through the responder chain. In order for a view controller to be able to validate a menu item, its view or one of its subviews will need to be the first responder. This means that you have to subclass the view, override ‘acceptsFirstResponder’ to return “YES” – AND that your user has to click in the view before going to the menu in order for the menu items to be usable.

    Placing the view controllers in the same part of the chain as the other controller classes ensures that the action message can travel to them, regardless of which view is the first responder. The controllers can then decide which items to validate based on their own internal logic.

  • To see the difference in behavior of the two approaches, change the sample code from the SimpleViewController2 project in the file MainWindowController.m, in the windowDidLoad: method:

    	// patch the detail view into the responder chain
    	NSResponder * aNextResponder = [self nextResponder];
    	[self setNextResponder:mDetailViewController];
    	[mDetailViewController setNextResponder:aNextResponder];
    

    to

    	// patch the detail view into the responder chain
    	NSResponder * aNextResponder = [aDetailView nextResponder];
    	[aDetailView setNextResponder:mDetailViewController];
    	[mDetailViewController setNextResponder:aNextResponder];
    

    After you make that change, build and run the project. Click within the detail view area to make it the window’s First Responder. Go to the ‘View’ menu and the items will be validated. Now click into the table view area and then return to the ‘View’ menu. The menu items won’t be validated. You will have to click in the detail view area again to validate the menu items. This isn’t the desired behavior for these menu items.

    Anyway…

    NSViewController and IB

    NSViewController is designed to be used with a nib file. As you can with NSWindowController, you will initialize a view controller with the name of its associated nib file.

    mTableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil];
    

    The view controller will automatically load the nib when it is asked to return its view for the first time. In order for all of this to go smoothly, there are two things to be sure to do in your nib file:

    1. Set the File’s Owner’s “Class” to be the NSViewController subclass that will be managing its view

    1. Drag the view controller’s header file into the IB project or use the “Read Class Files…” command in the File menu and select the header file.
    2. Select the “File’s Owner” object and go to “Identity” tab in the inspector palette. Start typing the class name of the view controller. It should autocomplete for you.
    Picture 16.png

    2. Connect the File’s Owner’s (your view controller) “view” outlet to the nib’s top level view.

    1. Ctrl-drag from “File’s Owner” to the view.
    2. Select the “view” outlet when the small context menu pops up.
    ConnectingOutlet.jpg

    That’s it!

    Resources

    NSViewController Class Reference

    Apple’s View Controller Sample Code (shows example of switching view controllers)

    NSResponder Class Reference

    The Responder Chain for Action Messages (from the docs on the Event Architecture)

    Tags: ,

    7 Responses to “Simple NSViewController Sample Projects”

    1. Joel Says:

      Nice, thanks a lot for this. I just discovered these XS classes, and I’m starting to wonder how I ever got along with them…

    2. Josh Says:

      Very helpful! Thanks!

    3. dreamcat7 Says:

      Hi - Any progress on re-work these XSViewController Classes to include nested geometries? If its no longer possible then maybe worthwhile to concentrate on hammering down the class specification for others to implement ?

      Personally I do not know any candidate however there certainly seems to be enough general interest to take this further e.g. Google summer-of-code project / or a post to cocoa-dev {at} lists.apple(.)com can renew this idea ? We have not seen any similar library classes and neither as ambitious or worthwhile in this area, so i believe it would be very welcome. Good work!

    4. Tianzhou Chen Says:

      I have a suggestion for the menu validate problem if setting the view’s next responder to its containing view controller.
      We can add validateMenuItem: to XSWindowController and also add a dictionary which holds all the menu items and its enable state. For the validateMenuItem: in XSViewController, rather than setting the menu item enable state directly, we set the corresponding value in that dictionary and then call [XSWindowController validateMenuItem:] to actually refresh the menu item enable state. Thus even for those menu items whose target is not the key view currently, they can still be validated based on the value in that dictionary(the lastest updated value)
      I prefer to have the view controller to be the next responder of its related view( Though I don’t see how much I can benefit from it, it just looks nature to me ). But surely your XSView&Window Controller will be the base upon which I further that work!

    5. Alexwebmaster Says:

      Hello webmaster
      I would like to share with you a link to your site
      write me here preonrelt {at} mail(.)ru

    6. Chris Says:

      thanks! I am new and have been searching and searching for some simple starting samples. This was an investment of your time to help others. It is nice to see a generous spirit. Thanks a lot!

    7. wncksuijytfc Says:

      gxscnhbhugdt

    Leave a Reply