button.bounds.offsetBy(dx: 0.0, dy: -20.0)
首先,不起作用的原因是因为这些坐标落在状态栏项目的“窗口”之外,即状态栏本身。所以它之外的任何东西都被裁剪了。
我通过在这里和那里收集信息解决了这个问题:
- 创建一个不可见的窗口。
- 找到状态栏项目在屏幕中的坐标,将不可见的窗口定位在其下方。
- 显示与
NSPopover
不可见窗口相关的,而不是状态栏项目。

红色的东西是不可见的窗口(用于演示目的)。
斯威夫特 4 (Xcode 9.2)
// Create a window
let invisibleWindow = NSWindow(contentRect: NSMakeRect(0, 0, 20, 5), styleMask: .borderless, backing: .buffered, defer: false)
invisibleWindow.backgroundColor = .red
invisibleWindow.alphaValue = 0
if let button = statusBarItem.button {
// 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)
// position and show the NSPopover
mainPopover.show(relativeTo: invisibleWindow.contentView!.frame, of: invisibleWindow.contentView!, preferredEdge: NSRectEdge.minY)
NSApp.activate(ignoringOtherApps: true)
}
我试图使用show(relativeTo: invisibleWindow.frame ...)
并且弹出窗口没有出现,因为NSWindow
它不是NSView
. 要显示弹出窗口,必须通过视图。