【发布时间】:2018-02-28 05:14:06
【问题描述】:
我正在开发一个 NSPopover 应用程序。我使用raywenderlich tutorial 作为起点。
我遇到的问题是,当弹出框打开并关闭系统状态栏时(例如在笔记本电脑上使用多个全屏应用程序时),弹出框显示在屏幕的左下方。
有没有办法在弹出框打开时强制系统状态栏打开并保持打开状态?
【问题讨论】:
-
你有没有解决这个问题?我打了大约 2 天,仍然没有进展:(
我正在开发一个 NSPopover 应用程序。我使用raywenderlich tutorial 作为起点。
我遇到的问题是,当弹出框打开并关闭系统状态栏时(例如在笔记本电脑上使用多个全屏应用程序时),弹出框显示在屏幕的左下方。
有没有办法在弹出框打开时强制系统状态栏打开并保持打开状态?
【问题讨论】:
我们遇到了类似的问题,最终检测到系统菜单栏何时最小化:
[NSMenu menuBarVisible]
就保持您的窗口可见,您可以考虑使用NSBorderlessWindowMask | NSNonactivatingPanelMask即时分享您的窗口样式
【讨论】:
问题是当状态栏不可见时,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)
}
}
【讨论】: