[SOLVED] Function called for all NSWindow

Issue

When I call function, it’s called for all window opened and not just for the selected window.

If the function is called by @IBAction It’s applied for the selected window. Otherwhise, it’s applied for all windows.
How can i call the function just for the current selected window ?

Here is an preview:
enter image description here

This is the minimal reproductible code:

//  AppDelegate.swift

import Cocoa

@main
class AppDelegate: NSObject, NSApplicationDelegate {

    @objc func openMyWindow()
        {
            let storyboard:NSStoryboard = NSStoryboard(name: "Main", bundle: nil)
            guard let controller:NSWindowController = storyboard.instantiateController(withIdentifier: "WindowMain") as? NSWindowController else { return }
            controller.showWindow(self)
        }
    
    @objc func test()
        {
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "TEST"), object: nil, userInfo: nil)
        }
    
    func applicationDockMenu(_ sender: NSApplication) -> NSMenu? {
        
        let dockMenu = NSMenu()
        dockMenu.addItem(withTitle: "New window", action: #selector(openMyWindow), keyEquivalent:     "")
        dockMenu.addItem(withTitle: "test", action: #selector(test), keyEquivalent:     "")
        return dockMenu
    }

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
        return true
    }


}
//  ViewController.swift

import Cocoa

class ViewController: NSViewController {
    
    @objc func Test(){
        
        TextView.string = "It's applied for ALL views -> it's NOT ok"
        
    }
    
    @IBAction func button(_ sender: Any) {
        
        TextView.string = "It's applied just for this view -> it's ok"
    }
    
    @IBOutlet var TextView: NSTextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        NotificationCenter.default.addObserver(self, selector: #selector(Test), name: NSNotification.Name(rawValue: "TEST"), object: nil)
  
    }

    override var representedObject: Any? {
        didSet {
        
        }
    }


}

Solution

Notification with object nil (no object) are hard to distinguish when it is not even evaluated which of the windows invoked the post.

In other words, make use of the object: parameter when you post the Notification.

Otherwise all registered observers in multiple windows will act on one and the same Notification.

So what object could be used to know who was sending?
The window object itself of course.

Your WindowController has a window it belongs to as well, just compare its address to the posted Notifications object and act when they are the same.
Or compare against the front most windows address, which usually is the window the user expects to act on commands given.

Answered By – Ol Sen

Answer Checked By – Marilyn (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.