This is the simplest way to put code together. For example in the Applicate Delegate, when it gets the -applicationDidFinishLaunching: message, the code might look something like that in the below...
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
/*************************************************************************\
|* Set up the UI for this application
\*************************************************************************/
AZView *contentView = [AZWindow contentViewForWindow:AZApp.window];
[contentView setIdentifier:@"content-view"];
/*************************************************************************\
|* Add a view that supports dragging, taking up the left hand side of the
|* window's content-view
\*************************************************************************/
NSRect bounds = contentView.bounds;
bounds.size.width /= 2;
DraggingView *left = [[DraggingView alloc] initWithFrame:bounds];
left.backgroundColour = [AZColour colourNamed:@"goldenrod"];
[contentView addSubview:left];
/*************************************************************************\
|* Add a view that supports dropping, taking up the right hand side of the
|* window's content-view
\*************************************************************************/
bounds = contentView.bounds;
bounds.size.width /= 2;
bounds.origin.x = bounds.size.width;
DroppingView *right = [[DroppingView alloc] initWithFrame:bounds];
right.backgroundColour = [AZColour colourNamed:@"snow"];
[contentView addSubview:right];
}
Here, we obtain the content-view (the top-level view that spans the entire window) of the application's window, and we add to it two separate views, one on the left ("DraggingView") which is acting as a drag-and-drop source, and one on the right ("DroppingView") which is acting as a drag-and-drop destination. Any view can be both source and destination, but this is an example that comes with the main project, and it's simpler to show when the functions are separated.
Note that the colour of each view is set as a property of the view, and there is a built-in list (actually the X11 list) of colours that can be used as names - though you can also specify in terms of uint8_t or float r,g,b,a values for colours.
This sets up the application below - obviously there is more code in the two views to provide the drag/drop funcitonality but the layout is just as above. You can see how I pick up the 'cyclone' image on the left, drag it over to the DroppingView (which gets notified as soon as the drag-action enters it) and as I move it around in the DroppingView, I get notifications (throttled to about 10/second) so I can update the view appropriately. Once I drop the the image over the target area, the information in the drag-and-drop pasteboard is displayed in the console.
Views can be given an auto-resizing mask (just like NSView) so when the window (or a parent view) is resized, the behaviour of the view is controllable - whether it proportionately follows the change in size, or position, or both, or whether it keeps the same size, position or both. I don't bother to set it in the above, but it's just a view property, like any other. Once the view hierarchy is created, it can therefore be responsive to window resizing in a manner in which you choose.
For more complex UI, it can be advantageous to use a UI builder - and Xcode on the Mac comes with Interface Builder built in. Interface Builder writes to a XIB file which is the in-development version of a NIB file, which is what AppKit actually uses. The XIB file is actually pretty verbose, so there is a tool called xib2zib which reads in a XIB file and produces a more-compact representation that is easier for the application to parse, saving it to a ZIB file.
The naming convention implies I ought to actually call it an 'AZIB' file (since I'm using the AZ namespace, and the IB stands for Interface Builder, "N" was NextStep, and "X" is "Xcode", all of which are *IB files). However, I'm also sticking to 3-character extensions, so its "A ZIB" file :)
When you create a ZIB file, you can include it as 'main.zib' in your application, and the framework will load it when your application starts, making the "File's Owner" into the AZApplication object, and (assuming you have one) linking through the window and ApplicationDelegate just like AppKit does. Any connections you make in the XIB file will transfer over to the ZIB file, so you can set up IBActions and IBOutlets just like in Interface builder.
There isn't any code (well, any non-framework code, there's quite a bit of framework code!) for this to happen, just make sure your custom class-types match up, so if you define MyView in Interface Builder, then make sure there's a MyView.{m,h} in your project. XCode knows nothing about the AZ namespace, so will make views with class NSView etc. but the ZIB loader will translate all the standard classes to the AZ namespace instead, so dragging in an NSSCrolllView or NSCollectionView will magically produce an AZScrollView or AZCollectionView in the ZIB file. It's relatively easy to come up with something like the below, which shows off several of the higher-level views (Scrollview, TableView, OutlineView, as well as several of the smaller control-like views)
Some of the views and controls are implemented differently to AppKit (radio buttons send Notifications, for example, rather than using NSMatrix which always seemed overly-complex to me). The basic patterns for the larger views remain the same however, with datasource and delegate as the main shared pattern. The methods will be comfortably similar to anyone who's programmed using AppKit before... Sufficiently so that tutorials on the internet for how to use (for example) NSTableView are equally applicable to AZTableView...
One thing worth noting for Interface Builder use is that IB is a little too clever, and won't let you create a CustonView class of AZView if your XCode project actually has AZView in it (which the main application almost certainly will) - because it knows AZView doesn't inherit from NSView...
The thing is you do want AZView (and custom subclass) instances in that XIB that will become main.zib, so that you can drag connections between objects. The solution is to open up a different Xcode sacrificial project, and create views there that are in the AZView hierarchy, and then just copy/paste them over to the real project's interface builder pane. IB won't complain about pre-existing classes being named "strangely".