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. Если получатель не отвечает, он отправляет это сообщение следующему ответчику с тем же селектором и объектом.

Другие вопросы по тегам