NSApp.sendAction() работает только через некоторое время
Я хочу, чтобы ViewController (ContainerVC) реагировал на нажатия пользовательских дочерних представлений (ChildView).
В ChildView я переопределяю mouseDown(_:)
обрабатывать щелчок. В этом методе я пытаюсь вызвать цель ContainerVC через NSApp.sendAction(#selector(ContainerVC.childViewClicked(_:)), to: nil, from: self)
,
По какой-то причине sendAction
метод завершается ошибкой (т.е. возвращает false) вначале. Также NSApp.target(forAction: #selector(ContainerVC.childViewClicked(_:))
ноль
Через некоторое время (обычно после того, как я какое-то время дико щелкаю по настраиваемым представлениям), цель решается, и все работает нормально, и вызывается ContainerVC.childViewClicked(_:).
Я не смог найти систематического паттерна, через какое время / сколько кликов цель была решена (кроме интенсивности моего крика на мой макинтош).
Интересно, что работает нормально, когда я добавляю ContainerVC в окно через let window = NSWindow(contentViewController: ContainerVC())
,
Странное поведение, описанное выше, возникает, когда я добавляю ContainerVC в разделенное представление:
self.addSplitViewItem(NSSplitViewItem(viewController: ContainerVC())
Я проверил цепочку респондента CustomView. ContainerVC появляется в цепочке, как и ожидалось. В цепочке нет других классов, которые реализуют childViewClicked (_:).
Я был бы признателен, если бы кто-то мог рассказать мне о внутренней работе NSApp.sendAction(_:) и о том, почему цель сначала равна нулю.
Есть ли дополнительные шаги, необходимые при добавлении ViewController в SplitView, чтобы правильно соединить вещи?
1 ответ
Из документации sendAction(_:to:from:)
:
Если aTarget равен nil, sharedApplication ищет объект, который может ответить на сообщение, то есть объект, который реализует метод, соответствующий aAction. Это начинается с первого респондента ключевого окна.
Когда ChildView не первый респондент, sendAction(_:to:from:)
не работает использование
func `try`(toPerform action: Selector, with object: Any?) -> Bool
например
self.`try`(toPerform: #selector(ContainerVC.childViewClicked(_:)), with: self)
который делает то, что вы хотите:
Если получатель отвечает на anAction, он вызывает метод с аргументом anObject и возвращает YES. Если получатель не отвечает, он отправляет это сообщение следующему ответчику с тем же селектором и объектом.