views:

92

answers:

1

Apparently, I've been working with bindings too long, because I can't figure out how to do this. I have a table with several columns. When a row is selected, you can edit its priority, which modifies a core data attribute. I've also set this as an IBAction. Basically, I want to access the value of the Core Data attribute from my code. Then, I want to set the first column of whatever row is selected (and had its priority changed) to a number of exclamation marks corresponding to the priority level.

Sorry this is worded confusingly; here's an example:

Row 7 is selected. I change its priority to 2. Now, the Core Data attribute myPriority is set to 2. A code block is now triggered. It gets the priority of the selected row (row 7) form Core Data and wants to set column 1 of the selected row (row 7) to 2 exclamation marks (priority 2).

Thanks!

+1  A: 

If you're used to bindings, then I'd recommend looking at NSValueTransformer; specifically, creating a subclass of that which converts a priority value to a string of exclamation marks. You'd then simply provide the name (the same one used in +setValueTransformer:forName:) as the 'value transformer' attribute in your bindings.

For instance, the code would look like so:

@interface PriorityTransformer : NSValueTransformer
@end

@implementation PriorityTransformer
+ (Class) transformedValueClass { return ( [NSString class] ); }
+ (BOOL) allowsReverseTransformation { return ( NO ); }
- (id) transformedValue: (id) value
{
    // this makes the string creation a bit simpler
    static unichar chars[MAX_PRIORITY_VALUE] = { 0 };
    if ( chars[0] == 0 )
    {
        // ideally you'd use a spinlock or such to ensure it's setup before 
        //  another thread uses it
        int i;
        for ( i = 0; i < MAX_PRIORITY_VALUE; i++ )
            chars[i] = (unichar) '!';
    }

    return ( [NSString stringWithCharacters: chars
                                     length: [value unsignedIntegerValue]] );
}
@end

You would then put this code into the same file as a central class (such as the application delegate) and register it through that class's +initialize method to ensure it's registered in time for any nibs to find it:

+ (void) initialize
{
    // +initialize is called for each class in a hierarchy, so always
    //  make sure you're being called for your *own* class, not some sub- or
    //  super-class which doesn't have its own implementation of this method
    if ( self != [MyClass class] )
        return;

    PriorityTransformer * obj = [[PriorityTransformer alloc] init];
    [NSValueTransformer setValueTransformer: obj forName: @"PriorityTransformer"];
    [obj release];   // obj is retained by the transformer lookup table
}
Jim Dovey