Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

xcode - How to prevent multiple instances of the same window of a Menu Bar App from opening in macOS in Swift 5?

I am making a MacOS Menu Bar app (Xcode 11.3.1, Swift 5.1.3) and in its popup window (that pops up when clicking on the icon in the menu bar - this is my Main.storyboard) it has a button to open the Preferences window.

So I actually need to show the Preferences window from the Main.storyboard that is on another storyboard called Preferences.storyboard.

Problem is that as many times I click the button on the Main storyboard a new Preferences window comes up on screen.

My initial code in the ViewController.swift of my Main.storyboard was:

class ViewController: NSViewController {
    
    private var preferencesWindowController: NSWindowController?

    let appDelegate = NSApplication.shared.delegate as! AppDelegate
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

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

    // MARK: - Shows the Preferences window on button click in popup bubble
    @IBAction func showPreferences(_ sender: Any) {
        
        if preferencesController == nil {
            let storyboard = NSStoryboard(name: "Preferences", bundle: nil)
            preferencesController = storyboard.instantiateInitialController() as? NSWindowController
        }
        
        if (preferencesController != nil) {
            preferencesController?.showWindow(sender)
        }
        
        NSApp.activate(ignoringOtherApps: true)
    }

}

This did not prevented showing new instances of the Preferences window upon clicking the button.

So I made the trick with the "lazy" var putting this code in the ViewController.swift of my Main.storyboard:

(as suggested at How to prevent multiple instances of the same window from opening in macOS? - note: there the example shows clicking a standard menu item, not a button in a menu bar popup window that seemed to fire an @IBAction code in my AppDelegate.swift, but for my menu bar app I do not have a menu to show at all, rather I would do all actions from the popup window of the menu bar icon)

class ViewController: NSViewController {
    
    private lazy var preferencesWindowController: NSWindowController? = {
        let storyboard: NSStoryboard = NSStoryboard(name: "Preferences", bundle: nil)
        return storyboard.instantiateInitialController() as? NSWindowController
    }()

    let appDelegate = NSApplication.shared.delegate as! AppDelegate
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

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

    // MARK: - Shows the Preferences window on button click in popup bubble
    @IBAction func showPreferences(_ sender: Any) {
        preferencesWindowController?.showWindow(self)
        NSApp.activate(ignoringOtherApps: true)
    }

}

On the Preferences.storyboard my Storyboard Entry Point and Initial Controller for the Preferences window is its Window Controller (in its Window Controller Scene) that contains a Tab View Controller (in its Tab View Controller Scene) with the settings.

I also did set the Presentation attribute of the Window Controller of the Preferences window to "Single" (as suggested at What is the difference between "Multiple" and "Single" for View Controller Presentation?).

I also tried using IB only: no IBAction coded, just connected the button to the built-in ViewController showPreferences:

All the same result: I can open a new Preferences window with a new click on the button as may times as I click.

What do I miss?

question from:https://stackoverflow.com/questions/65898276/how-to-prevent-multiple-instances-of-the-same-window-of-a-menu-bar-app-from-open

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...