Apparently I was working around a problem that no longer exists for most common 
cases.  You don't need to do any shenanigans with replacing or overriding 
-initWithCoder: to get custom cells to work from IB anymore.  To get a custom 
cell class unarchived directly from the nib, just keep clicking on a control 
until you notice that the inspector window's title has changed to the name of 
the cell class (e.g. for a search field the title would change from "Search 
Field..." to "Search Field Cell...").  Then navigate to the Identity tab (the i 
in a circle) and set the class to your custom cell class name.  Viola... less 
code, yay!

Hope this helps someone.

->Ben

On Oct 18, 2010, at 6:22 PM, Ben Lachman wrote:

> 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/blachman%40mac.com
> 
> This email sent to [email protected]

--
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