我试图在基于NSOutlineView的源列表的底部添加一个按钮栏,如在许多Mac应用程序(苹果和第三方)中所见,如以下屏幕快照所示:


为了用文字描述它,控制栏共享源列表的特殊样式的渐变背景(或在优胜美地下,“充满活力”),而不会重叠任何源列表的内容。为了重现这种效果,到目前为止,我已经尝试了以下方法:

  • 在源列表的滚动 View 的剪辑 View 的底部添加带有按钮栏高度的额外“填充”,并允许该栏与源 ListView 重叠。仅当按钮栏背景不透明且不会将滚动条移开时,此方法才有效。
  • 使用NSBox es,其背景设置为源列表的backgroundColor属性提供的NSColor。这需要大量强制重绘才能正确绘制(特别是在窗口处于事件状态/处于非事件状态时),但否则看起来很完美。使用设置为绘制渐变背景的自定义NSView可以看到类似的行为。

  • 还有其他方法可以用来实现这一目标吗? #2是我能找到的最接近的,但考虑到它带来的问题,显然它不打算由第三方开发人员使用。

    在优胜美地中使用Vibrancy进行操作应该很简单,只需检查Yosemite并插入启用了Vibrancy的NSVisualEffectView即可。另一方面,将其正确设置在10.8/10.9以下...

    我可以通过使用NSWindow提供的内置底部条形图完全避开此问题,但是颜色合并的方法在外观上更加整洁,将控件与其父 Pane 紧密关联,并且似乎是首选的样式,这些天更频繁。如果可能的话,我想在自己的应用程序中使用它。

    最佳答案

    通过包含NSView的子类并在包含窗口的键状态更改时使用KVO观察颜色更改,可以使此工作正常进行。由于您提到的原因(活力),它在10.10上不起作用,但在10.9上却可以正常工作。

    Apple Mailing List上的Sourcelist background colors线程为我解决了这个问题。

    界面:

    #import <Cocoa/Cocoa.h>
    
    @interface SourceListColoredView : NSView
    @end
    

    实现:
    #import "SourceListColoredView.h"
    
    @interface SourceListColoredView ()
    @property (nonatomic, strong) NSColor *backgroundColor;
    @property (nonatomic, assign, getter = isObservingKeyState) BOOL observingKeyState;
    @end
    
    @implementation SourceListColoredView
    
    - (id)initWithFrame:(NSRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            [self addWindowKeyStateObservers];
        }
        return self;
    }
    
    - (void)awakeFromNib
    {
        NSOutlineView *outlineView = [[NSOutlineView alloc] init];
        [outlineView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
        self.backgroundColor = [outlineView backgroundColor];
        [self addWindowKeyStateObservers];
    }
    
    - (void)addWindowKeyStateObservers
    {
        if (!self.isObservingKeyState) {
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(redisplay)
                                                         name:NSWindowDidBecomeKeyNotification
                                                       object:[self window]];
    
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(redisplay)
                                                         name:NSWindowDidResignKeyNotification
                                                       object:[self window]];
        }
        self.observingKeyState = YES;
    }
    
    - (void)redisplay
    {
        [self setNeedsDisplay:YES];
    }
    
    - (void)dealloc
    {
        if (self.isObservingKeyState) {
            [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeKeyNotification object:[self window]];
            [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResignKeyNotification object:[self window]];
        }
    }
    
    - (void)drawRect:(NSRect)dirtyRect
    {
        [_backgroundColor setFill];
        NSRectFill(dirtyRect);
    }
    
    @end
    

    您可能必须将-awakeFromNib中的代码移到其他位置,具体取决于初始化 View 的方式。

    关于objective-c - 将控件/按钮栏添加到配置为源列表的NSOutlineView的底部,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26938326/

    10-10 03:55