Hi all.

I have a work around for the problem that one runs into with custom subclassed 
controls that use custom cells being unarchived from nibs with standard cells.  
(this is covered many place, possibly most succinctly here: 
http://mikeash.com/pyblog/custom-nscells-done-right.html)

This works for every custom control I've written, including several types of 
buttons.  However the most recent custom checkbox I was working on today 
displays an odd behavior.  Instead of setting the cell class back to 
NSButtonCell correctly after unarchiving, it skips out of the method and moves 
to the next item to unarchive and doesn't come back until after all the rest of 
the cells have been unarchived.  This leads to any other NSButtonCells to be 
unarchived as my custom button cell subclass leading to odd appearances.

Any thoughts on why this might be happening would be instructive... 

My NSControl category looks thusly:

@implementation NSControl (CellClass)

+ (void) initialize { 
    [[[self class] superclass] initialize]; 
    Class NSControlClass = [NSControl class]; 
    
method_exchangeImplementations(class_getInstanceMethod(NSControlClass,@selector(initWithCoder:)),class_getInstanceMethod(NSControlClass,@selector(newInitWithCoder:)));
} 

- (id) newInitWithCoder:(NSCoder *)origCoder { 
        BOOL sub = YES;
        
        sub = sub && [origCoder isKindOfClass: [NSKeyedUnarchiver class]]; // 
no support for 10.1 nibs
        sub = sub && ![self isMemberOfClass: [NSControl class]]; // no raw 
NSControls
        sub = sub && [[self superclass] cellClass] != nil; // need to have 
something to substitute
        sub = sub && [[self superclass] cellClass] != [[self class] cellClass]; 
// pointless if same
        sub = sub && ([NSStringFromClass( [[self class] cellClass]) 
hasPrefix:@"NS"] == NO);
        
        if( !sub ) {
                self = [self newInitWithCoder:origCoder]; 
        } else {
                NSKeyedUnarchiver *unarchiver = (id)origCoder;
                
                // gather info about the superclass's cell and save the 
archiver's old mapping
                Class superCell = [[self superclass] cellClass];
                NSString *oldClassName = NSStringFromClass( superCell );
                Class oldClass = [unarchiver classForClassName:oldClassName];
                if( !oldClass )
                        oldClass = superCell;
                
                // override what comes out of the unarchiver
                [unarchiver setClass: [[self class] cellClass] 
forClassName:oldClassName];
                
                // unarchive
                NSLog( @"unarchiving %@", NSStringFromClass([[self class] 
cellClass]));
                self = [self newInitWithCoder:origCoder];
                NSLog( @"done.");
                
                // set it back
                [unarchiver setClass:oldClass forClassName:oldClassName];       
                
        }
        
        return self;
}       

And the debug console look like this: 

2010-10-18 17:41:53.500 UI-test[54499:a0f] unarchiving CustomSearchFieldCell
2010-10-18 17:41:53.503 UI-test[54499:a0f] done.
2010-10-18 17:41:53.505 UI-test[54499:a0f] unarchiving DarkCheckboxButtonCell  
<---- this is the checkbox
2010-10-18 17:41:53.506 UI-test[54499:a0f] unarchiving DarkTextFieldCell
2010-10-18 17:41:53.507 UI-test[54499:a0f] done.
2010-10-18 17:41:53.508 UI-test[54499:a0f] unarchiving DarkTextFieldCell
2010-10-18 17:41:53.509 UI-test[54499:a0f] done.
2010-10-18 17:41:53.514 UI-test[54499:a0f] unarchiving GradientButtonCell
2010-10-18 17:41:53.530 UI-test[54499:a0f] done.
2010-10-18 17:41:53.530 UI-test[54499:a0f] unarchiving GradientButtonCell
2010-10-18 17:41:53.531 UI-test[54499:a0f] done.
2010-10-18 17:41:53.533 UI-test[54499:a0f] unarchiving GradientButtonCell
2010-10-18 17:41:53.534 UI-test[54499:a0f] done.
2010-10-18 17:41:53.535 UI-test[54499:a0f] done. <---- this is where it set the 
old class back


--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

email: [email protected]
twitter: @benlachman
mobile: 740.590.0009

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to