Presentation single with code

(swift, macOS, storyboards)

I open a window with code. Every time the user clicks the button the same window opens again and again. How to avoid that?

This opens well the window, but multiple times:

    @IBAction func obrirAmbCodi(_ sender: NSButton) {

        let storyboard:NSStoryboard = NSStoryboard(name: "Main", bundle: nil)

        guard let controller:NSWindowController = storyboard.instantiateController(withIdentifier: "finestra3") as? NSWindowController else { return }

            controller.showWindow(self)

    }

If I open the window with a segue (storyboard control drag) I can accomplish that by selecting the window controller > Attributes > Presentation > Single. But it seems that it does not work if I open the window with code

Every time the user clicks the button the same window opens again and again. How to avoid that?

It is not clear what you want to do. But I guess you just want to activate the window if it is already opened.

Then, you should not instantiate a new instance at each time:

    private var controller: NSWindowController? = {
        let storyboard:NSStoryboard = NSStoryboard(name: "Main", bundle: nil)
        return storyboard.instantiateController(withIdentifier: "finestra3") as? NSWindowController
    }()
    
    @IBAction func obrirAmbCodi(_ sender: NSButton) {
        controller?.showWindow(self)
    }

Could you explain better what you get and what you want ?

I try to formulate

  • You click button, calling obrirAmbCodi, which opens a window finestra3
  • when you click again on that button, a new, similar window opens (probably stacked over previous one ?)
  • in such a case, you would want just to display the already opened window, not create a new one.

Is that correct ?

If so, you could:

  • In the class where obrirAmbCodi is, declare a var

var controller: NSWindowController?

  • test if nil ; if so instantiate
    @IBAction func obrirAmbCodi(_ sender: NSButton) {
        if controller == nil {
            let storyboard:NSStoryboard = NSStoryboard(name: "Main", bundle: nil)
            controller = storyboard.instantiateController(withIdentifier: "finestra3") as? NSWindowController  // could be nil
            controller?.showWindow(self)
        }
    }
  • dismiss the controller when you close window and set to nil

Note: you could test if the window is open instead of testing controller

Presentation single with code
 
 
Q