3

Im trying to make so if the user clicks on the menu icon to show the popover that the popover closes if the user clicks anywhere but popover. I set the behavior to transient but thats not doing what I thought.

Now if the user clicks somewhere on the popover bringing focus to it, then the user can click somewhere else on the screen and the popover will close. If I could force a focus to the popover I think that would fix my problem as well. Unfortunately I dont know how to do that either.

class AppDelegate: NSObject, NSApplicationDelegate {

    let view : NSView!
    let statusItem: NSStatusItem
    let popover: NSPopover
    let button : NSButton!

    override init() {

        statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
        if let statusButton = statusItem.button {
            appStatusButton = statusButton
            statusButton.image = NSImage(named: "icon128off")
            statusButton.alternateImage = NSImage(named: "icon128")
            statusButton.action = "onPress:"
        }

        popover = NSPopover()
        popover.animates = false
        popover.contentViewController = ViewController()
        popover.behavior = .Transient
    }


}

Here is the view controller

class ViewController: NSViewController, WKNavigationDelegate{

   var webView : WKWebView!

   override func loadView() {
      view = NSView()
      view.translatesAutoresizingMaskIntoConstraints = false
      view.addConstraint(NSLayoutConstraint(
        item: view, attribute: .Width, relatedBy: .Equal,
        toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 580))
      view.addConstraint(NSLayoutConstraint(
        item: view, attribute: .Height, relatedBy: .Equal,
        toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 425))

    }
}
John Pollard
  • 3,729
  • 3
  • 24
  • 50

5 Answers5

9

Swift 5.1

Problem is that the PopOver's Window is not becoming key, to fix this just force it to become key just after showing it. For example supposing pop is a NSPopOver:

pop.show(relativeTo: button.bounds, of: button, preferredEdge: .minY)
pop.contentViewController?.view.window?.makeKey()
vicegax
  • 4,709
  • 28
  • 37
6

Swift 5:

NSApplication.shared.activate(ignoringOtherApps: true)

Add this right before you open the popup

NSApplication.sharedApplication().activateIgnoringOtherApps(true)

Thanks to this guy!

Rocket Nikita
  • 470
  • 2
  • 7
  • 20
John Pollard
  • 3,729
  • 3
  • 24
  • 50
2

I have faced with the exact same issue, none of the answers works for me. But i tried a combination of showing below which works flawlessly

        self.popover.behavior = NSPopover.Behavior.transient
        NSApp.activate(ignoringOtherApps: true)
        self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
Gurhan Polat
  • 696
  • 5
  • 12
0

I do not recommend to use behaviour property of the popover. It is better to handle it in your application. see how it is done in this link I answered almost same problem. Xcode Swift OS X popover behavior

Community
  • 1
  • 1
Nasim Saleh
  • 181
  • 1
  • 7
0

With addition to John Pollard's answer

If you're using Swift 4+, Add this code before showing the popup:

NSApplication.shared.activate(ignoringOtherApps: true)
Avi L
  • 1,558
  • 2
  • 15
  • 33