Ключевые команды контроллера просмотра включены, когда он представлен модально - PullRequest
0 голосов
/ 07 мая 2020

Я работаю над добавлением сочетаний клавиш в свое приложение. Есть контроллер представления, который представляет другой контроллер:

class ViewController: UIViewController {

    override var canBecomeFirstResponder: Bool { true }

    override func viewDidLoad() {
        super.viewDidLoad()

        addKeyCommand(UIKeyCommand(
            input: "M",
            modifierFlags: .command,
            action: #selector(ViewController.handleKeyCommand),
            discoverabilityTitle: "Command from the container view"
        ))
    }

    @objc func handleKeyCommand() {
        present(ModalViewController(), animated: true)
    }

    override func canPerformAction(
        _ action: Selector, withSender sender: Any?
    ) -> Bool {
        if action == #selector(ViewController.handleKeyCommand) {
            return isFirstResponder
        }

        return super.canPerformAction(action, withSender: sender)
    }
}

class ModalViewController: UIViewController {

    override var canBecomeFirstResponder: Bool { true }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .white
        addKeyCommand(UIKeyCommand(
            input: "D",
            modifierFlags: .command,
            action: #selector(ModalViewController.handleKeyCommand),
            discoverabilityTitle: "Command from the modal view"
        ))

        if !becomeFirstResponder() {
            print("⚠️ modal did not become first responder")
        }
    }

    @objc func handleKeyCommand() {
        dismiss(animated: true)
    }
}

Оба определяют ярлыки. Когда представлен контроллер модального представления, всплывающее окно «Обнаруживаемость» включает ярлыки как для представляющего, так и для представленного контроллера представления. Интуитивно понятно, что должны быть включены только ярлыки контроллера модального представления (мы не должны иметь возможность взаимодействовать с контроллером представления представления, верно?)

Я могу исправить это, переопределив свойство keyCommands контроллера представления представления , но это хорошая идея?

В общем, в чем причина такого поведения? Это ошибка или особенность?

ОБНОВЛЕНИЕ : добавлен canPerformAction(_:sender:) в контроллер представления представления (как было предложено @ buzzert ), но проблема сохраняется.

1 Ответ

1 голос
/ 25 июня 2020

Это происходит потому, что представляющий контроллер представления (ViewController) - это ваш ModalViewController nextResponder в цепочке респондентов.

Это связано с тем, что ОС требуется какой-то способ трассировки из представления контроллер, который в настоящее время отображается на экране, вплоть до приложения.

Если ваш контроллер представления представления имеет команды, которые имеют смысл только тогда, когда он является первым респондентом, самый простой способ решить эту проблему - просто переопределить canPerformAction(_:) на ViewController и вернуть false, если это не первый респондент.

Например,

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if self.isFirstResponder {
            return super.canPerformAction(action, withSender: sender)
        } else {
            return false
        }
    }

В противном случае, если вы хотите получить больший контроль над nextResponder в цепочку респондента, вы также можете переопределить геттер nextResponder, чтобы «пропустить» контроллер представления представления. Это не рекомендуется, но служит иллюстрацией того, как это работает.

...