Dan Wood is co-owner of Karelia Software, creating programs for the Macintosh computer. He is the father of two kids, lives in the Bay Area of California USA, and prefers bicycles to cars. This site is his weblog, which mostly covers geeky topics like Macs and Mac Programming.
Useful Tidbits and Egotistical Musings from Dan Wood
Categories: Mac OS X · Cocoa Programming · General · All Categories
permanent link
· Topic/Cocoa
|
OK, I finally have something interesting to write about in the "Cocoa" category. I'm going to talk about Class Posing.
On the application I'm working on, I want to be able to support textured iApp-like windows, but not require them. There are probably some sophisticated ways to handle this choice, but the biggest restriction is that you can't change the style of an NSWindow once that window has been initialized. And if you are loading a window from a nib, the window has already been initialized!
I was struggling to come up with a solution that would avoid having to create two almost identical nib files for each window type: one textured, one untextured. Then I came up with the solution: use posing!
What I've done is to create a new subclass of NSWindow called MyPosingWindow. It intercepts the initialization, and checks the preferences to see if the window should be changed to a textured window, and then lets NSWindow do its stuff.
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)styleMask
backing:(NSBackingStoreType)backingType
defer:(BOOL)flag
{
NSUserDefaults *defaults
= [NSUserDefaults standardUserDefaults];
BOOL useTextured =
[defaults boolForKey:@"UseTexturedWindows"];
unsigned int newMask = styleMask | (useTextured
? NSTexturedBackgroundWindowMask
: 0);
return [super initWithContentRect:contentRect
styleMask:newMask
backing:backingType
defer:flag];
}
All that I need to get this hooked up is the following line in my application delegate's +initialize method:
[MyPosingWindow poseAsClass: [NSWindow class]];
Posing, though it's great for hacks and trickery, is also a really useful tool when used properly. Back in Watson, I used posing to make all NSTableView objects support alternate-row striping, without having to change the class in every nib file. Similarly, I used posing to bring extra behaviors to NSComboBox to improve auto-completion. And a couple of other cases, which I don't recall offhand. So Cocoa developers, do not fear the power of posing!
(And yes, that's actual code and an actual partial screenshot of my upcoming application — I hope that doesn't give too much away!)