Monday, October 5, 2009

Binding an image (to a checkbox)

This is a straightforward extension of other bindings we did recently. Click on the checkbox, if it becomes "ON" you get the chimp, if it's "OFF" you get President Bush.

The underlying data that supports the table view is an array of dictionaries (for KVC compliance), each with the key "isOn" and a boolean value. For convenience, the data is stored in a plist file and loaded into the project, as shown here.

There is a checkbox cell in the first table column's data cell, and an image cell in the second column's cell. Editing has been disabled for the second column. (We don't know how to turn an image into a boolean!)

The images are png files, added to the project as usual. They can be loaded in two different ways, as shown in the code. You could set it up variously, but I load the images in the App Delegate and then the value transformer asks for them, so getter methods are implemented in the App Delegate (not shown).

It all works great. There is only one problem: the images in the table view are washed out. Compare the originals:

I don't know why this is.

The bindings are straightforward. There is an array controller in the nib. It is connected like:

The first table column has this binding:

And the second table column has this binding:

Here is the code for the init method of the App Delegate where the data is loaded:

- (id)init
self = [super init];
if (nil == self) { return nil; }
{ NSLog(@"DataSource init"); }
NSString *fn = [[NSBundle mainBundle]
pathForResource:@"data" ofType:@"plist"];
temp = [NSArray arrayWithContentsOfFile:fn];
[self setA:[temp mutableCopy]];
NSLog(@"%@", A);
fn = [[NSBundle mainBundle]
pathForResource:@"bush" ofType:@"png"];
bush = [[NSImage alloc] initWithContentsOfFile:fn];
[bush retain];
chimp = [NSImage imageNamed:@"chimp"];
[chimp retain];
NSLog(@"%@", bush);
return self;

And this is the implementation of the Value Transformer:

- (id)init {
self = [super init];
if (self == nil) return nil;
bush = [[NSApp delegate] bush];
chimp = [[NSApp delegate] chimp];
return self;

+ (Class)transformedValueClass{
return [NSImage class];

+ (Class)allowsReverseTransformation {
return NO;

- (NSImage *)transformedValue:(id)value {
if (nil == value) { return nil; }
bool flag = [value boolValue];
if (!(flag)) { return bush; }
else { return chimp; }

No comments: