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]
