更改NSWindow边框颜色

3

我需要改变我的应用程序NSWindow周围的边框颜色。

有人知道窗口边框在哪里绘制,以及如何更改颜色/覆盖绘制边框的方法吗?

我注意到Tweetbot做到了这一点:

常规边框 vs Tweetbot 边框


这里是一个猜测:如果你调用[self.window.contentView setBorderType:NSNoBorder];,看看它是否完全消除了边框?从那时起,你可以自己绘制。 - sudo rm -rf
@sudorm-rf 这里没有运气 :/ - Alex Marchant
是的,我就知道那样行不通。主要问题在于 NSWindow 实际上使用私有 CGS 函数在主内容之外绘制此边框。除非您使用无边框窗口,否则我似乎记不起任何删除此边框的方法。 - sudo rm -rf
@sudorm-rf 看起来contentView的superview是一个叫做NSThemeFrame的东西。http://parmanoir.com/Custom_NSThemeFrame 我猜那里绘制了边框,但不确定。 - Alex Marchant
不,实际上根据我的判断它在视图层次结构之外。 - sudo rm -rf
@sudorm-rf 哦,你说得对,我只是在 NSThemeFrame 中覆盖了 drawRect,所以还是有边框的。 - Alex Marchant
1个回答

2

据我记忆,Tweetbot使用了一个完全无边框的窗口,并添加了窗口控件本身,但如果您想让AppKit仍然处理这些细节,还有另一种方法。如果将窗口设置为纹理窗口,则可以设置自定义背景NSColor。这个NSColor可以使用+[NSColor colorWithPatternImage:]来设置图像。

我很快地举了一个例子,只是使用了纯灰色作为填充,但您可以在此图像中绘制任何您喜欢的东西。然后,您只需要将NSWindow的类类型设置为您的纹理窗口类即可。

SLFTexturedWindow.h

@interface SLFTexturedWindow : NSWindow
@end

SLFTexturedWindow.m

#import "SLFTexturedWindow.h"

@implementation SLFTexturedWindow

- (id)initWithContentRect:(NSRect)contentRect
                styleMask:(NSUInteger)styleMask
                  backing:(NSBackingStoreType)bufferingType
                    defer:(BOOL)flag;
{
    NSUInteger newStyle;
if (styleMask & NSTexturedBackgroundWindowMask) {
    newStyle = styleMask;
} else {
    newStyle = (NSTexturedBackgroundWindowMask | styleMask);
}

if (self = [super initWithContentRect:contentRect styleMask:newStyle backing:bufferingType defer:flag]) {

    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(windowDidResize:)
                                                     name:NSWindowDidResizeNotification
                                                   object:self];

        [self setBackgroundColor:[self addBorderToBackground]];

        return self;
}

return nil;
}

- (void)windowDidResize:(NSNotification *)aNotification
{
    [self setBackgroundColor:[self addBorderToBackground]];
}

- (NSColor *)addBorderToBackground
{
    NSImage *bg = [[NSImage alloc] initWithSize:[self frame].size];
    // Begin drawing into our main image
[bg lockFocus];

[[NSColor lightGrayColor] set];
NSRectFill(NSMakeRect(0, 0, [bg size].width, [bg size].height));

    [[NSColor blackColor] set];

    NSRect bounds = NSMakeRect(0, 0, [self frame].size.width, [self frame].size.height);
    NSBezierPath *border = [NSBezierPath bezierPathWithRoundedRect:bounds xRadius:3 yRadius:3];
    [border stroke];

    [bg unlockFocus];

    return [NSColor colorWithPatternImage:bg];  
}

@end

实际上,看起来这会导致窗口有两个边框,一个黑色的内部边框和一个灰色的外部边框。http://cl.ly/image/201s0X0S1F3Q - Alex Marchant
是的,看来你是对的。对此我很抱歉,我即使仔细看了也没有看到灰色边框(可能是因为视力不好和视网膜屏幕的结合)。看起来你需要使用无边框窗口方法并自己绘制标题栏。 - iain
是的,我也有Retina屏幕,我不得不把它带到Photoshop中检查其他边框:P感谢您的帮助。 - Alex Marchant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接