如何在OSX中改变NSWindow标题栏的颜色

Mur*_*m K 19 macos cocoa titlebar nswindow

经过长时间搜索NSWindow标题栏颜色和标题颜色后,我找到了一个简单的绘图解决方案.我张贴这个来分享我的知识.

Mur*_*m K 24

子类a NSView带有名称MyTitleView并添加以下代码

- (void)drawString:(NSString *)string inRect:(NSRect)rect {
    static NSDictionary *att = nil;
    if (!att) {
        NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
        [style setLineBreakMode:NSLineBreakByTruncatingTail];
        [style setAlignment:NSCenterTextAlignment];
        att = [[NSDictionary alloc] initWithObjectsAndKeys: style, NSParagraphStyleAttributeName,[NSColor whiteColor], NSForegroundColorAttributeName,[NSFont fontWithName:@"Helvetica" size:12], NSFontAttributeName, nil];
        [style release];

    }

    NSRect titlebarRect = NSMakeRect(rect.origin.x+20, rect.origin.y-4, rect.size.width, rect.size.height);


    [string drawInRect:titlebarRect withAttributes:att];
}


- (void)drawRect:(NSRect)dirtyRect
{
    NSRect windowFrame = [NSWindow  frameRectForContentRect:[[[self window] contentView] bounds] styleMask:[[self window] styleMask]];
    NSRect contentBounds = [[[self window] contentView] bounds];

    NSRect titlebarRect = NSMakeRect(0, 0, self.bounds.size.width, windowFrame.size.height - contentBounds.size.height);
    titlebarRect.origin.y = self.bounds.size.height - titlebarRect.size.height;

    NSRect topHalf, bottomHalf;
    NSDivideRect(titlebarRect, &topHalf, &bottomHalf, floor(titlebarRect.size.height / 2.0), NSMaxYEdge);

    NSBezierPath * path = [NSBezierPath bezierPathWithRoundedRect:self.bounds xRadius:4.0 yRadius:4.0];
    [[NSBezierPath bezierPathWithRect:titlebarRect] addClip];



    NSGradient * gradient1 = [[[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.0 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:1 alpha:1.0]] autorelease];
    NSGradient * gradient2 = [[[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:1 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0 alpha:1.0]] autorelease];

  [path addClip];


//    [[NSColor colorWithCalibratedWhite:0.00 alpha:1.0] set];
//   [path fill];


   [gradient1 drawInRect:topHalf angle:270.0];
    [gradient2 drawInRect:bottomHalf angle:270.0];

    [[NSColor blackColor] set];
    NSRectFill(NSMakeRect(0, -4, self.bounds.size.width, 1.0));


    [self drawString:@"My Title" inRect:titlebarRect];


}
Run Code Online (Sandbox Code Playgroud)

在appDelegate中导入类MyTitleView并添加以下代码

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSRect boundsRect = [[[_window contentView] superview] bounds];
    BlackTitlebarView * titleview = [[BlackTitlebarView alloc] initWithFrame:boundsRect];
    [titleview setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];

    [[[_window contentView] superview] addSubview:titleview positioned:NSWindowBelow relativeTo:[[[[_window contentView] superview] subviews] objectAtIndex:0]];
}
Run Code Online (Sandbox Code Playgroud)

  • 这绝对有效,但Apple确实注意到Yosemite:"自WWDC种子以来的新功能:NSWindow从未支持客户将子视图添加到contentView以外的任何内容.有些应用程序会将子视图添加到contentView.superview(也称为边框视图)当它检测到这种情况时,NSWindow现在会记录:"NSWindow警告:添加一个未知的子视图:".执行此操作的应用程序需要解决此问题,因为它会阻止10.10上的新功能正常工作.请参阅titlebarAccessoryViewControllers官方API." (9认同)

Sam*_*aus 23

有一种更容易的方法来做到这一点.我已经读过你可以在Storyboard/.xib文件中将窗口的外观更改为"纹理",但这并不完全有效(标题栏颜色是斑驳的).但是,您只需两行即可更改代码中的颜色:

window.titlebarAppearsTransparent = true // gives it "flat" look
window.backgroundColor = <NSColor> // set the background color
Run Code Online (Sandbox Code Playgroud)