【问题标题】:How to Change Color of NSWindow Title Bar in OSX如何在 OSX 中更改 NSWindow 标题栏的颜色
【发布时间】:2013-11-29 17:28:40
【问题描述】:

在长时间搜索NSWindow 标题栏颜色和标题颜色后,我找到了一个简单的绘图解决方案。我发布这个是为了分享我的知识。

【问题讨论】:

标签: macos cocoa nswindow titlebar


【解决方案1】:

有一种更简单的方法可以做到这一点。我读过您可以在 Storyboard / .xib 文件中将窗口的外观更改为“纹理”,但这并不完全有效(标题栏颜色斑驳)。但是,您可以只用两行代码更改颜色:

window.titlebarAppearsTransparent = true // gives it "flat" look
window.backgroundColor = <NSColor> // set the background color

【讨论】:

  • @Tommy 没问题。
  • 这是最简单也更优雅的方式。谢谢。
  • 这种方法有一个缺陷:当你想从那个窗口展示一个工作表模式时,工作表会从窗口的顶部边缘下降,而不是从标题栏下面......跨度>
  • @Lvsti Hmmm.. 我从来不需要在我的项目中展示表单模式,所以我不知道该怎么做。我只是想我会分享我遇到的东西,这样人们就不必从上面复制一百行 Objective-C 代码。 ://
  • 这很棒,但是如果我将它设置为深色,窗口标题仍然是黑色的,并且很难阅读。有什么方法可以设置窗口标题的颜色?
【解决方案2】:

子类 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];


}

在 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]];
}

【讨论】:

  • 这绝对有效,但 Apple 确实注意到,从 Yosemite 开始:“自 WWDC 种子以来的新功能:NSWindow 从未支持客户端将子视图添加到除 contentView 之外的任何内容。某些应用程序会将子视图添加到 contentView。超级视图(也称为窗口的边框视图)。NSWindow 现在将在检测到这种情况时记录:“NSWindow 警告:添加未知子视图:”。执行此操作的应用程序将需要解决此问题,因为它会阻止新功能从 10.10 开始正常工作。请参阅 titlebarAccessoryViewControllers 获取官方 API。"
【解决方案3】:

OSX 10.10 上没有警告消息。像这样

NSView *windowTopView = [[_window standardWindowButton:NSWindowCloseButton] superview];

-(void) applicationDidFinishLaunching:(NSNotification *)aNotification {

NSRect boundsRect = [windowTopView bounds];

NSView *windowTopView = [[_window standardWindowButton:NSWindowCloseButton] superview];
BTitleView * titleview = [[BTitleView alloc] initWithFrame:boundsRect];
[titleview setTitleImagePath:[[NSBundle mainBundle] pathForResource:@"Top1-01" ofType:@"bmp"]] ;
[titleview setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[windowTopView addSubview:titleview positioned:NSWindowBelow relativeTo:[[windowTopView subviews] objectAtIndex:0]];

//addTitlebarAccessoryViewController
NSTitlebarAccessoryViewController *dummyTitlebarAccessoryViewController;
NSView * logoview = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 10, 11)];
dummyTitlebarAccessoryViewController = [NSTitlebarAccessoryViewController new];
dummyTitlebarAccessoryViewController.view = logoview;
dummyTitlebarAccessoryViewController.fullScreenMinHeight = 0;
[_window addTitlebarAccessoryViewController:dummyTitlebarAccessoryViewController];


}

【讨论】:

    猜你喜欢
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2011-01-29
    • 2011-06-06
    • 2011-10-12
    相关资源
    最近更新 更多