2008 03 20Establishing manual Cocoa Bindings
But now we have some IB-exotic data, like a dual choice orientation between landscape/portrait, and we want a custom NSControl or custom NSView to edit it. (Radio buttons must know their limits) How do we bind our data to our new control ? Interface Builder won't let us do it, it will only let us bind keyPaths it knows. So we have to do it … manually. With code. Argh.
bind:toObject:withKeyPath:options:
is the binding function. But ... which way do we bind ? Do we bind from controller to view, or view to controller ? And how do we get notifications of change ?
Thanks to key value observing (KVO), addObserver:forKeyPath:options:context:
will spy on an object for us and notify of a keyPath change. So we call bind, then add an observer … which way do we bind already ?
As we're observing, we'll let the views observe the controller. When the controller changes, views will be notified. Then, to bind arrayController.selection.orientation
and view.orientation
, we call [view bind:viewKeyPath toObject:controller withKeyPath:controllerKeyPath options:…]
.
We override view's bind method and in it, start observing the controller for keyPath change with [controller addObserver:view forKeyPath:controllerKeyPath options:… context:…];
. KVO will then notify us of any controller keyPath change by calling our view with observeValueForKeyPath:ofObject:change:context:
.
That's it ! Pretty simple once you understand what gets bound to what, and how notifications are called. Here's a recap of data flow :
When model changes | When view changes |
Check out WebViewControl for sample code.
Cocoa Bindings
- WebViewControl Sample code for custom bindings : binding Cocoa to an html page
- Establishing manual Cocoa Bindings Bindings in a custom NSView
- Custom cocoa bindings What I'd like to see in IB to setup custom bindings
- Bindings via KVC only In Leopard, your properties are bindable without any extra work
- Bindings, Outlets, Target+Action across multiple NIBs