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

时间:2009-11-03 03:55:19

标签: objective-c cocoa macos

我想自定义我在OS X上绘制窗口标题栏的方式。具体来说,我想做一些像Twitterrific应用程序,其中有自定义关闭按钮,没有最小/最大按钮,以及窗口标题文本是右对齐的。与Twitterrific不同,我不打算自定义绘制整个窗口(虽然我并不完全反对)。

我已经在Cocoa With Love以及Apple提供的RoundTransparentWindow示例中看到了RoundWindow示例,但似乎都不合适。

3 个答案:

答案 0 :(得分:6)

如果您不想使用无边界窗口类,那么您可以做几件事。

首先,您可以使用-[NSWindow standardWindowButton:]自定义关闭/最小/最大按钮。获得按钮后,您可以将其定位/移除/等等......

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

这可能是最简单的做事方式。

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

NSWindow的内容视图位于“主题视图”中。您可以继承主题视图并执行自己的绘图。唯一的问题是主题视图是一个私人类,所以你必须要小心。

答案 1 :(得分:5)

cocoadev提供了有关如何最好地实现自己的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子类,使用所述类的实例填充整个窗口,然后在该自定义视图中执行所有相应的窗口绘制。

整件事情可能会有点痛苦。您将不得不重新实现大多数常规窗口行为,例如通过拖动右下角来调整大小。

答案 2 :(得分:2)

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