【问题标题】:How to open a NSPopover at a distance from the system bar?如何在远离系统栏的地方打开 NSPopover?
【发布时间】:2018-07-13 15:14:49
【问题描述】:

我正在通过状态栏中的图标操作打开NSPopover

myPopover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)

除了弹出框和系统栏的距离为零之外,这可以正常工作:

我想实现与 Dropbox 应用相同的结果,它在距系统栏一小段距离处呈现弹出框:

我尝试使用button.bounds.offsetBy(dx: 0.0, dy: 20.0),它不会影响弹出框的位置,button.bounds.offsetBy(dx: 0.0, dy: -20.0) 将弹出框置于系统栏上方:

那么我怎样才能将NSPopover 定位在离系统栏一定距离的地方呢?

【问题讨论】:

  • 在黑暗中拍摄,但您是否尝试过不同的坐标系?类似myPopover.show(relativeTo: button.frame.insetBy(dx: 0.0, dy: -8.0), of: button.superview, preferredEdge: NSRectEdge.minY)
  • 刚试了一下,不管是正值还是负值都没有效果。

标签: swift macos cocoa nspopover nsstatusbar


【解决方案1】:

首先,button.bounds.offsetBy(dx: 0.0, dy: -20.0) 不起作用的原因是因为这些坐标落在状态栏项目的“窗口”之外,即状态栏本身。所以它之外的任何东西都被裁剪了。

我通过到处收集信息解决了这个问题:

  1. 创建一个不可见的窗口。
  2. 在屏幕中找到状态栏项目的坐标,将不可见的窗口定位在它的下方。
  3. 显示与不可见窗口相关的NSPopover,而不是状态栏项目。

红色的东西是不可见的窗口(用于演示目的)。

Swift 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。要显示弹出窗口,必须传递一个视图。

【讨论】:

  • 很好的解决方案——但是,即使我使用NSApp.activate(ignoringOtherApps: true),NSPopover 也无法集中注意力。任何线索如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 2019-10-30
  • 2017-03-17
相关资源
最近更新 更多