如何获取 NSWindow 的默认标题栏高度?

16

我创建了一个OS/X应用程序,当它运行时,我将窗口定位在屏幕中央。为了实现这一点,我在计算y值时必须包含标题栏高度。

有没有办法确定默认标题栏的高度?根据我对其他窗口系统的经验,我希望(需要)以某种方式查询窗口管理器...


我认为你可能需要做一些技巧来找出内容视图,并确定它在窗口中的位置...请参阅https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/index.html#//apple_ref/doc/uid/20000014-SW25 - Grady Player
你可以在IB中配置窗口来完成这项任务。 - uchuugaka
7
我不使用IB。它让我感觉很不舒服。 - Suppy
顺便提一下,你也可以直接调用NSWindow.center()来完成此操作,而无需进行复杂的框架大小和标题栏高度计算。 - Ky -
3个回答

18

我想出了这个解决方案。请注意,当窗口的styleMask包括fullSizeContentView时,返回值为0.0,因为在这种情况下,标题栏实际上没有高度。

作为Swift扩展:

extension NSWindow {
    var titlebarHeight: CGFloat {
        frame.height - contentRect(forFrameRect: frame).height
    }
}

使用方法:

let titlebarHeight = someWindow.titlebarHeight

作为 Objective-C 的类别扩展:

@implementation NSWindow (TitleBarHeight)

- (CGFloat) titlebarHeight
{
    return self.frame.size.height - [self contentRectForFrameRect: self.frame].size.height;
}

@end

使用方法:

CGFloat titlebarHeight = someWindow.titlebarHeight;

如果你想把一个 fullSizeContentView 窗口视为带有标题栏的窗口,你可以从窗口按钮的大小和位置推断出标题栏的高度。 - Ky -

9

使用 .fullSizeContentViewNSWindow 上时计算工具栏/标题栏区域高度的解决方案

if let windowFrameHeight = self.view.window?.contentView?.frame.height,
    let contentLayoutRectHeight = self.view.window?.contentLayoutRect.height {
    let fullSizeContentViewNoContentAreaHeight = windowFrameHeight - contentLayoutRectHeight
}

fullSizeContentViewNoContentAreaHeight是您所需的高度。 这很重要,因为如果您的应用程序使用NSDocument并且用户创建了一个新文档,则系统可能会在新标签中打开此新文档。 您可以在updateViewConstraints()中执行此操作以检测此类更改。

来源:https://developer.apple.com/videos/play/wwdc2016/239/


3
我可能漏掉了什么,但我将 windowFrameHeight 的值更改为 view.window?.frame.height,这使我得到了正确的高度,而不管窗口是否具有全尺寸内容视图。非常有用。在 NSWindow 上作为扩展同样适用:var titleBarHeight: CGFloat { return frame.height - contentLayoutRect.height } - robotspacer

6

不清楚您是想将内容矩形居中,然后建立框架矩形以保持内容矩形居中,还是想将框架矩形居中并且对应的关心内容矩形。

无论哪种情况,NSWindow都有一些有用的方法。在你有实例之前,你可以使用类方法+frameRectForContentRect:styleMask:+contentRectForFrameRect:styleMask:。这些方法考虑了窗口样式所表示的样式掩码,但不考虑任何工具栏最终窗口可能拥有。

如果你正在使用现有实例,你可以使用方法-frameRectForContentRect:-contentRectForFrameRect:。这些方法使用窗口的当前样式,并考虑其工具栏。(工具栏位于框架矩形内而不是内容矩形内。)

您似乎决定使用屏幕的实际中心来放置窗口。但是,您应该考虑使用NSWindow-center方法。它水平居中窗口,但实际上比屏幕的真正垂直中心更高。这是故意这样做的,因为这被认为对用户更加突出和直接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接