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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1665147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 06:31:16  来源:igfitidea点击:

How to custom draw window title bar in Objective-C?

objective-ccocoamacos

提问by sam

I'd like to customize the way I draw the window title bar on OS X. Specifically, I'd like to do something like the Twitterrific app where there is a custom close button, no min/max buttons, and the window title text is right-justified. Unlike Twitterrific, I'm not looking to custom draw the entire window (though I'm not completely opposed to that either).

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

I've already seen the RoundWindow sample on Cocoa With Love as well as the RoundTransparentWindow example Apple provides, but neither seems appropriate.

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

采纳答案by Leibowitzn

If you don't want to use a borderless window class then you can do a couple of things.

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

First, you can customize the close/min/max buttons buy using -[NSWindow standardWindowButton:]. Once you get the button you can position it/remove it/etc...

首先,您可以使用 自定义关闭/最小/最大按钮购买-[NSWindow standardWindowButton:]。一旦你得到按钮,你就可以定位/移除它/等等......

You can customize the title by setting the title to @"". Then you can add a NSTextFieldto draw your own title by doing the following [[[NSWindow contentView] superview] addSubview:textField].

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

This is probably the easiest way to do things.

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

Another way to do this is to customize the view that draws all the window title bar, etc...

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

NSWindow's content view's is inside a "theme view". You can subclass the theme view and do your own drawing. The only problem is that the theme view is a private class so you'll have to be careful.

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

回答by e.James

cocoadevprovides some more detail on how best to implement your own NSWindowsubclass, complete with a description of most of the common pitfalls.

cocoadev提供了有关如何最好地实现您自己的NSWindow子类的更多详细信息,并完成了对大多数常见陷阱的描述。

The gist of it is to create a subclass of NSWindow, and set its styleMaskto NSBorderlessWindowMaskin the init method:

它的要点是创建一个 的子类NSWindow,并在 init 方法中将其设置styleMaskNSBorderlessWindowMask

- (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;
}

Note that you should probably return YES for canbecomeKeyWindowin order to make your window behave like a normal window.

请注意,您可能应该返回 YEScanbecomeKeyWindow以使您的窗口表现得像一个普通窗口。

- (BOOL) canBecomeKeyWindow
{
    return YES;
}

You can then create a custom NSView subclass, fill the entire window with an instance of said class, and then perform all of the appropriate window drawing from within that custom view.

然后,您可以创建一个自定义 NSView 子类,用该类的实例填充整个窗口,然后从该自定义视图中执行所有适当的窗口绘制。

The whole thing can get a bit painful. You will have to re-implement most of the normal window behaviours such as resizing by dragging the bottom right corner.

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

回答by NSResponder

There's an example of a custom window implementation in the CoreData Stickies sample project.

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