當我呼叫函式時,它會為所有打開的視窗呼叫,而不僅僅是為選定的視窗呼叫。
如果該函式由@IBAction它呼叫,則應用于所選視窗。否則,它適用于所有視窗。如何僅為當前選定的視窗呼叫該函式?
這是一個預覽:

這是最小的可復制代碼:
// 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 {
}
}
}
uj5u.com熱心網友回復:
當甚至沒有評估哪個視窗呼叫了該帖子時,帶有物件 nil(無物件)的通知很難區分。
換句話說,object:在您發布通知時使用該引數。
否則,多個視窗中的所有注冊觀察者都將作用于同一個通知。
那么什么物件可以用來知道誰在發送呢?當然是視窗物件本身。
您的 WindowController 也有一個屬于它的視窗,只需將其地址與發布的 Notifications 物件進行比較,并在它們相同時采取行動。或者與最前面的視窗地址進行比較,該地址通常是用戶希望對給定命令執行操作的視窗。
uj5u.com熱心網友回復:
如果未設定選單項的目標,則將操作訊息發送給第一回應者。在您看來,文本視圖是第一個回應者,但它不處理test訊息并將其發送給下一個回應者。視圖控制器位于回應者鏈中,并將接收test訊息。將選單項的選擇器設定為視圖控制器的動作,前窗的視圖控制器將接收到它。無需通知。
// AppDelegate.swift
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
@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)
}
func applicationDockMenu(_ sender: NSApplication) -> NSMenu? {
let dockMenu = NSMenu()
dockMenu.addItem(withTitle: "New window", action: #selector(openMyWindow), keyEquivalent: "")
dockMenu.addItem(withTitle: "test", action: #selector(ViewController.test), keyEquivalent: "")
return dockMenu
}
}
// ViewController.swift
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
@objc func test() {
TextView.string = "It's applied for this view -> it's now ok"
}
@IBAction func button(_ sender: Any) {
TextView.string = "It's applied just for this view -> it's ok"
}
@IBOutlet var TextView: NSTextView!
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/445610.html
