问题
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)
}
}
回答3:
Update for Swift 4+
var detector: AnyObject?
// make sure you add this just before you open the popup.
detector = NSEvent.addGlobalMonitorForEvents(matching:[NSEvent.EventTypeMask.leftMouseDown, NSEvent.EventTypeMask.rightMouseDown], handler: { [weak self] event in
self?.hidingFunction()
}) as AnyObject
func hidingFunction(){
popover.performClose(nil)
if let temp: AnyObject = detector { // using if let to be sure it was intialized
NSEvent.removeMonitor(temp)
}
}
来源:https://stackoverflow.com/questions/32685453/xcode-swift-os-x-popover-behavior