NSTabView with background color

2019-02-11 05:06发布

问题:

As discussed elsewhere, NSTabView does not have a setBackgroundColor method and subclassing NSTabView and using an drawRect to control it does no longer work - as it does not paint the top 10%, the bit just below the segmented control button.

Now I am a bit surprised by the amounts of work arounds I had to do solving this; see

  • code: https://github.com/dirkx/CustomizableTabView/blob/master/CustomizableTabView/CustomizableTabView.m

and am wondering if i went down the wrong path. And how to do this better & simpler:

  • The NSSegmentStyleTexturedSquare seems to yield me a semi-transparent segmented Control. Which means I need to do extra work to hide any bezel lines (line 240, 253).

    • is there a better way to do this ? I.e. negate its transparency ?

    • or is there a way I can use the actual/original segmented choise button ?

  • I find that the colours I need - like the [NSColor windowBackgroundColour] are not set to anything useful (i.e. that one is transparent) -- so right now I hardcode them (lines 87, 94).

    • Is there a better way to do this ?
  • I find I need a boatload of fluffy methods to keep things in sync ( line 128, 134, etc).

    • can this be avoided ?
  • I find that mimicking the cleverness on rescaling means I need to keep a constant eye on the segemented Control box and remove/resize it. And even then - it is not quite as good as the original

    • is there a better way to do this than line 157 -- i.e. hear about resizing ? Rather than do it all the time ?
  • The segementControl fades dark when focus is removed from the window - unlike the real McCoy.

    • can that easily be prevented ? is there a cheap way to track this ?
  • Or is this the wrong approach - and should I focus on just a transparent hole here - and let the NSTabViewItem draw a background ? But in any case - then I still have the issue with the Segemented COntrol box - or is there than a way to make that be the default again.

    • when trying this - I get stuck on the top 20-30 pixels being drawn in the 'real' windows background colour - which is 'transparent' - and hence the colour will not run all the way to the top or behind the segment bar and up to the bezel - but instead stop some 8 pixels below the bottom of the segment controls.

Feedback appreciated - as this feels so far off/suboptimal for such a simple things -- Thanks a lot. Brownie points for hacking/forking the github code :) :) :) As a line of running code says more than a thousand words.

Dw.

回答1:

PSMTabBarControl is probably the best workaround for you. I have created several custom tab views, but cocoa does not play well with this control. PSMTabBarControl has been updated to support Xcode 4. https://github.com/ciaran/psmtabbarcontrol



回答2:

Have you tried setting the background color of its underlying CALayer? (Make it a layer-backed view, if it isn't already, by setting wantsLayer = YES.)



回答3:

If your situation can tolerate some fragility, a very simple and quick approach is to subclass NSTabView and manually adjust the frame of the item subviews. This gives each item a seamless yellow background:

- (void)drawRect:(NSRect)dirtyRect {
    static const NSRect offsetRect = (NSRect) { -2, -16, 4, 18 };

    NSRect rect = self.contentRect;

    rect.origin.x += offsetRect.origin.x;
    rect.origin.y += offsetRect.origin.y;
    rect.size.width += offsetRect.size.width;
    rect.size.height += offsetRect.size.height;

    [[NSColor yellowColor] set];
    NSRectFill(rect);

    [super drawRect:dirtyRect];
}

A future change in the metrics of NSTabView would obviously be a problem so proceed at your own risk!