Establishing manual Cocoa Bindings

Thanks to Interface Builder, we can setup most of our interface with drag and drop, without resorting to too much custom code. Interface Builder will let us setup controllers, views, and establish how data flows among them by following the MVC (Model/View/Controller) model.


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 Image:BindingModelUpdate.png When view changes Image:BindingViewUpdate.png

Check out WebViewControl for sample code.

Cocoa Bindings

Follow me on Twitter
Planet Cocoa

2011 02 22Distance field
2010 07 202Binding through NSApp
2010 05 122Forwarding invocations
2010 02 272Core Image black fringes
2010 02 21Quickest Way to Shell
2010 02 08Who's calling ?
2009 09 2138 ways to use Blocks in Snow Leopard
2009 08 182Bracket Mess
2009 08 124Taming JavascriptCore within and without WebView
2009 04 15Debugging with Activity Monitor
2009 03 25How Core Image Color Tracking works
2009 03 1510Custom NSThemeFrame
2009 03 10Which framework is running ?
2009 03 074CoreUI can paint pretty big
2009 02 18Localization with functions
2009 01 30Did you forget to nest alloc and init?
2009 01 16JSCocoa on the iPhone
2009 01 11Mixing WebView and JavascriptCore
2009 01 09Badge overflow
2009 01 09Find your Garbage Collection leaks with Instruments

Powered by MediaWiki