views:

277

answers:

3

In IB it is easy to bind a label or text field to some controller's keyPath.

The NSDockTile (available via [[NSApp dockTile] setBadgeLabel:@"123"]) doesn't appear in IB, and I cannot figure out how to programmatically bind its "badgeLabel" property like you might bind a label/textfield/table column.

Any ideas?

+2  A: 

If NSDockTile does support bindings, you can use the method bind:toObject:withKeyPath:options: to set up bindings on the badgeLabel property. Check the documentation for details on which arguments to use. If it doesn't work, you could either implement key value observing in your controller class and update the label each time the value changes, or even override NSDockTile to create a bindings compatible subclass.

Marc Charbonneau
A: 

I've tried lots of variations of bind:toObject:withKeyPath:options: on NSDockTile, on a controller, on the data source. I can't figure out a combination that works. Alternately, is there a way of having a BatchController object that can be bound to the data source, and it then updates the badge? How do I take an NSObject and make it bindable?

Dr Nic
You don't. If an object doesn't explicitly support binding to a property, then it's probably doing things that would make the binding behave erratically (e.g., directly assigning to its ivar). Binding to it anyway will manifest that behavior in your app.
Peter Hosey
+3  A: 

NSDockTile doesn't have any bindings, so your controller will have to update the dock tile manually. You could do this using KVO which would have the same effect as binding it.

Create a context as a global:


static void* MyContext=(void*)@"MyContext";

Then, in your init method:


[objectYouWantToWatch addObserver:self forKeyPath:@"dockTileNumber" options:0 context:MyContext];

You then have to implement this method to be notified of changes to the key path:

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == MyContext) {
     [[NSApp dockTile] setBadgeLabel:[object valueForKeyPath:keyPath]];
    }
    else {
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

Make sure you remove the observer when the controller object goes away.

Rob Keniger