4

A Tale of Two Subclasses

By Ben Stock

Prologue

I'm in the process of making a really nice looking set of controls which automatically change their appearance depending on the type of window they're used in (e.g. If you drop a button in a normal window, it looks like any other standard Aqua button. If you drop it on an NSPanel with a window mask of NSHUDWindowMask, however, it'll automatically switch its style to look good on a HUD background. So far, I've subclassed NSButton, NSTextField, NSSlider, and NSSearchField. Last night I started on NSTabView, only to be slammed down by its lack of customizability. It's a real pain in the ass, but I'm a developer, so I'm used to finding my own way. The first thing I think to do is add an instance of NSSegmentedControl in place of the private tabs used by NSTabView. So far, so good. I've got the buttons selectable, they automatically update when new NSTabViewItem's are added, and they work just like the real thing.

And the Pain Begins …</h2>

Finally, I start to style my segments, and … WTF have I gotten myself into‽ I should've just gone into acting or something. Objective-C development is slowly taking years off my life. No matter what I do, the "tracking areas" used by NSSegmentedCell don't seem to be updating when my segment widths change. So when my widths change, my artwork does, too. However, the actual tracking area doesn't update (even when I override -updateTrackingAreas. It's really hard to explain, so I decided to draw my segment rectangles behind and in front of the ones drawn by super in -drawSegment:inFrame:withView. Here's a screenshot with my art drawn on top of the underlying tracking areas:

A HUD Panel in Mac OS X displaying debug rectangles.

And here's super's implementation above my segment rects:

enter image description here

I've tried overriding everything I can think of. Here are a few of the methods I've overridden (and un-overridden):

  • -cellSize (NSSegmentedCell)
  • -cellSizeForBounds: (NSSegmentedCell)
  • -sizeToFit (NSSegmentedControl)
  • -intrinsicContentSize (NSSegmentedControl)
  • -setWidth:forSegment: (NSSegmentedControl/Cell)
  • -startTrackingAt:inView: (NSSegmentedCell)
  • -continueTracking:at:inView: (NSSegmentedCell)
  • -stopTracking:at:inView:mouseIsUp: (NSSegmentedCell)

At this point, some of those methods in the above list are still using my overrides and some aren't. I've mixed and matched, deleted, simplified, rewrote, and refactored, and no matter what I do, the underlying rectangles don't change. I love Apple as much as the next guy, but their view of customization needs to change. I can't stand not being able to understand what's going on in the implementation of all these stupid controls. Not to mention the fact that I still can't fully wrap my head around Auto Layout (which is about the most un-"auto" thing I've ever dealt with), but that's a post for another day. Anyway, if anybody could help a brotha out, I'd be super grateful. Sorry for ranting and thanks for reading!

P.S. None of these things are finished, so please don't be too hard on a few pixel imperfections. ;-)

4

0 回答 0