Xcode Swift OS X popover behavior

2019-04-17 11:42发布

问题:

For my small Mac menubar application I'd like the behavior of the popover to be transient, so when it loses focus, it will close. This works for that:

popover.behavior = NSPopoverBehavior.Transient

But it only works once, so the second time you click somewhere else the popover stays. I placed the code in func applicationDidFinishLaunching(notification: NSNotification), but placing it outside this function inside the class did not work. How can I use force this behavior all the time?

I am using Xcode 7.0 with Swift (2.0).

回答1:

You better leave the behaviour to the default value which is NSPopoverBehaviorApplicationDefined and you implement necessary function to handle it.Because as it says in Apple Documentation the circumstances of the other two behaviours are not clear. You can do as follows:

detector = NSEvent.addGlobalMonitorForEventsMatchingMask([NSEventMask.LeftMouseDownMask, NSEventMask.RightMouseDownMask], handler: { [weak self] event in
                self?.hidingFunction()
            })

this registers a montior to a global event when left/right click is performed
Now you implement the hidingFunction() in the same class you made the above call in as the handler was specified as self.
This function will close the popover and and remove the monitor created

func hidingFunction(){
 popover.close()
 if let temp: AnyObject = detector { // using if let to be sure it was intialized
    NSEvent.removeMonitor(temp)
} 

detector is just a variable name you can name it whatever you want define it before at the top of the class as type of any object

var detector: AnyObject?


回答2:

Update for Swift 3

var detector: Any?

detector = NSEvent.addGlobalMonitorForEvents(matching:[NSEventMask.leftMouseDown, NSEventMask.rightMouseDown], handler: { [weak self] event in
        self?.hidingFunction()
    })

func hidingFunction() {
    popover.close()
    if let temp: Any = detector { // using if let to be sure it was intialized
        NSEvent.removeMonitor(temp)
    }
}