【问题标题】:NSPopover application does not always appear where it shouldNSPopover 应用程序并不总是出现在它应该出现的位置
【发布时间】:2018-02-28 05:14:06
【问题描述】:

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

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

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

【问题讨论】:

  • 你有没有解决这个问题?我打了大约 2 天,仍然没有进展:(

标签: cocoa appkit nspopover


【解决方案1】:

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

[NSMenu menuBarVisible]

就保持您的窗口可见,您可以考虑使用NSBorderlessWindowMask | NSNonactivatingPanelMask即时分享您的窗口样式

【讨论】:

  • [NSMenu menuBarVisible] 始终返回 true,即使应用程序全屏且状态栏已关闭。
  • 哦,很奇怪,我们很幸运,该方法返回了菜单栏可见性的可靠状态。
【解决方案2】:

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

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

因此,如果您将窗口保存为变量并显示与此相关的弹出框,您最终会得到如下结果:

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)
    }
}

【讨论】:

  • 不错!我很高兴这至少有时可以解决问题。如果您不首先通过状态栏打开应用程序(而是在状态栏隐藏时以编程方式打开),这不起作用!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-19
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 2015-01-23
相关资源
最近更新 更多