如何在Objective-C中自定义绘制窗口标题栏?

如何在Objective-C中自定义绘制窗口标题栏?,objective-c,cocoa,macos,Objective C,Cocoa,Macos,我想自定义在OS X上绘制窗口标题栏的方式。具体来说,我想做一些类似Twitterrific应用程序的事情,其中有一个自定义关闭按钮,没有最小/最大按钮,窗口标题文本是右对齐的。与Twitterrific不同,我不希望自定义绘制整个窗口(尽管我也不完全反对) 我已经在Cocoa With Love上看到了RoundWindow示例以及苹果提供的RoundTransparentTwindow示例,但这两个示例似乎都不合适。提供了关于如何最好地实现自己的NSWindow子类的更多细节,并对大多数常见

我想自定义在OS X上绘制窗口标题栏的方式。具体来说,我想做一些类似Twitterrific应用程序的事情,其中有一个自定义关闭按钮,没有最小/最大按钮,窗口标题文本是右对齐的。与Twitterrific不同,我不希望自定义绘制整个窗口(尽管我也不完全反对)

我已经在Cocoa With Love上看到了RoundWindow示例以及苹果提供的RoundTransparentTwindow示例,但这两个示例似乎都不合适。

提供了关于如何最好地实现自己的
NSWindow
子类的更多细节,并对大多数常见陷阱进行了描述

其要点是创建
NSWindow
的子类,并在init方法中将其
styleMask
设置为
NSBorderlessWindowMask

- (id) initWithContentRect: (NSRect) contentRect
                 styleMask: (unsigned int) aStyle
                   backing: (NSBackingStoreType) bufferingType
                     defer: (BOOL) flag
{
    if ((self = [super initWithContentRect: contentRect
                                 styleMask: NSBorderlessWindowMask
                                   backing: bufferingType
                                     defer: flag]) == nil) { return nil; }

    [super setMovableByWindowBackground:YES];
    [super setLevel:NSNormalWindowLevel];
    [super setHasShadow:YES];
    // etc.

    return self;
}
请注意,您可能应该为
canbecomeKeyWindow
返回YES,以便使您的窗口像普通窗口一样工作

- (BOOL) canBecomeKeyWindow
{
    return YES;
}
然后,您可以创建一个自定义NSView子类,用所述类的实例填充整个窗口,然后从该自定义视图中执行所有适当的窗口绘制


整个事情可能会有点痛苦。您必须重新实现大多数正常的窗口行为,例如通过拖动右下角来调整大小。

如果您不想使用无边界窗口类,那么您可以做一些事情

首先,您可以使用
-[NSWindow standardWindowButton::
自定义close/min/max按钮。一旦你得到按钮,你就可以定位/移除它/等等

您可以通过将标题设置为
@“
来自定义标题。然后,您可以添加一个
NSTextField
来绘制自己的标题,方法是执行以下
[[NSWindow contentView]superview]addSubview:textField]

这可能是最简单的方法

另一种方法是自定义绘制所有窗口标题栏的视图,等等


NSWindow的内容视图位于“主题视图”内。您可以对主题视图进行子类化并绘制自己的图形。唯一的问题是主题视图是一个私有类,因此您必须小心。

在CoreData Stickies示例项目中有一个自定义窗口实现的示例。

谢谢,eJames。你是对的,这种方法(我之前已经开始了)会变得很痛苦。我希望避免它,因为我不寻求完全的定制,也不想实现窗口的所有标准功能。这种方法基本上就是我在问题中引用的示例中使用的方法。这种方法的一个奇怪方面是窗口的阴影似乎无法正常工作。它不像标准窗口上的阴影那样暗,而且焦点改变时也不会改变。我认为这可能是一个无边界窗口样式的错误。阴影问题很奇怪。听起来莱博维森的答案可能是你的出路。祝你好运!影子问题是一个长期存在的问题。苹果没有为有键盘焦点的无边框窗口画出更暗的阴影。以胶粘物为例。据一家苹果公司介绍,解决这个问题的推荐方法是使用普通的窗口类型,然后自己绘制。谢谢你,莱博维森。能否提供有关如何设置NSTextField的更多详细信息?我如何设置它的框架,使其正确地定位在窗口中,并在我的代码中的哪个位置是执行此操作的最佳位置?FWIW,我是在应用程序控制器的awakeFromNib方法中完成的。我相对于窗口的框架定位了textfield的框架。这可能不是最好的方法,但我使用通知来了解窗口何时变为/退出主窗口,并使用它来更改文本的颜色。再次感谢你的建议。