如何以编程方式关闭 Mac 菜单栏应用程序中使用的 NSPopover

How to programatically close NSPopover being used in Mac Menu bar app

抱歉,这是一个新手问题。 我正在使用 https://github.com/davidcaddy/MenuBarPopoverExample 创建一个简单的菜单栏应用程序。

我在 viewController 中添加了一个按钮并连接了它。

关闭 NSPopover 的命令是什么(请参阅下面的评论部分)?

查看控制器代码:

import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    static func newInstance() -> ViewController {
        let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
        let identifier = NSStoryboard.SceneIdentifier("ViewController")
      
        guard let viewcontroller = storyboard.instantiateController(withIdentifier: identifier) as? ViewController else {
            fatalError("Unable to instantiate ViewController in Main.storyboard!")
        }
        return viewcontroller
    }
    
    
    @IBAction func closePopover(_ sender: Any) {
        print("close this popover")
        
        // what code would I put here??
       // closePopover(self)?

    }
}

AppDeligate 代码(示例未修改):

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength)
    let popover = NSPopover()
    var eventMonitor: EventMonitor?
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        if let button = self.statusItem.button {
            button.image = NSImage(named: NSImage.Name("ExampleMenuBarIcon"))
            button.action = #selector(AppDelegate.togglePopover(_:))
            
            // Uncomment this to capture right mouse clicks, in addition to left clicks
            //
            // button.sendAction(on: [.leftMouseUp, .rightMouseUp])
        }
        
        self.popover.contentViewController = ViewController.newInstance()
        self.popover.animates = false
        
        self.eventMonitor = EventMonitor(mask: [.leftMouseDown, .rightMouseDown]) { [weak self] event in
            if let strongSelf = self, strongSelf.popover.isShown {
                strongSelf.closePopover(sender: event)
            }
        }
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    @objc func togglePopover(_ sender: NSStatusItem) {
        // if sendAction(on: [.leftMouseUp, .rightMouseUp]) is uncommented in applicationDidFinishLaunching
        // This can be used to check the type of the incoming mouse event
        //
        // let event = NSApp.currentEvent!
        // if event.type == NSEvent.EventType.rightMouseUp {
        //     print("Right Click")
        // }
        
        if self.popover.isShown {
            closePopover(sender: sender)
        }
        else {
            showPopover(sender: sender)
        }
    }

    func showPopover(sender: Any?) {
        if let button = self.statusItem.button {
            self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
            self.eventMonitor?.start()
        }
    }

    func closePopover(sender: Any?) {
        self.popover.performClose(sender)
        self.eventMonitor?.stop()
    }
}

我已经尝试了我可以在网上找到的每个命令,其中 none 允许我从 ViewController 中以编程方式关闭弹出窗口。 如果您能提供任何帮助,我将不胜感激。

只需获取 AppDelegate 实例

@IBAction func closePopover(_ sender: Any) {
    let appDelegate = NSApp.delegate as! AppDelegate
    appDelegate.closePopover(self)
}

注意:由于sender参数实际上没有被使用,您可以在显示和关闭函数中省略它

func showPopover()