NSPopover应用程序并不总是出现在应有的位置

问题描述 投票:3回答:2

我正在开发NSPopover应用程序。我使用raywenderlich tutorial作为起点。

我遇到的问题是当弹出窗口打开并且系统状态栏关闭时(例如在笔记本电脑上使用多个全屏应用程序时),弹出窗口显示在屏幕的左下方。

在弹出窗口打开时,有没有办法强制系统状态栏打开并保持打开状态?

cocoa appkit nspopover
2个回答
2
投票

我们遇到了类似的问题,并最终检测到系统菜单栏何时被最小化:

[NSMenu menuBarVisible]

至于保持窗口可见,您可以使用NSBorderlessWindowMask | NSNonactivatingPanelMask动态分享您的窗口样式


0
投票

问题是当状态栏不可见时,statusItem /按钮有一个奇怪的位置,所以它位于屏幕的左侧。

一个可能的解决方案是在首次打开弹出窗口时保存位置并相对于该点继续显示它。在这个answer中,他们将popover相对于一个看不见的窗口。这是我们需要的,因为当我们显示相对于statusItem / button的popover时,如果状态不可见,则位置很奇怪。

因此,如果您将窗口保存为变量并显示相对于此的弹出窗口,您将最终得到如下内容:

static let popover = NSPopover()
var invisibleWindow: NSWindow!

func showPopover(sender: Any?) {
    if let button = AppDelegate.statusItem.button {
        if (invisibleWindow == nil) {
            invisibleWindow = NSWindow(contentRect: NSMakeRect(0, 0, 20, 1), styleMask: .borderless, backing: .buffered, defer: false)
            invisibleWindow.backgroundColor = .red
            invisibleWindow.alphaValue = 0

            // find the coordinates of the statusBarItem in screen space
            let buttonRect:NSRect = button.convert(button.bounds, to: nil)
            let screenRect:NSRect = button.window!.convertToScreen(buttonRect)

            // calculate the bottom center position (10 is the half of the window width)
            let posX = screenRect.origin.x + (screenRect.width / 2) - 10
            let posY = screenRect.origin.y

            // position and show the window
            invisibleWindow.setFrameOrigin(NSPoint(x: posX, y: posY))
            invisibleWindow.makeKeyAndOrderFront(self)
        }

        AppDelegate.popover.show(relativeTo: invisibleWindow.contentView!.frame, of: invisibleWindow.contentView!, preferredEdge: NSRectEdge.minY)
        NSApp.activate(ignoringOtherApps: true)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.