我正在努力为我的应用程序添加键盘快捷键。有一个显示另一个 Controller 的 View Controller :
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)
}
}
两者都定义了快捷方式。呈现模态视图 Controller 时,可发现性弹出窗口包括用于呈现和呈现 View Controller 的快捷方式。直觉上,只应包含模态视图 Controller 快捷方式(我们不应该能够与呈现 View Controller 交互,对吧?)
我可以通过覆盖呈现 View Controller 的 keyCommands
属性来解决这个问题,但这是个好主意吗?
一般来说,这种行为背后的原因是什么?这是错误还是功能?
更新:将 canPerformAction(_:sender:)
添加到呈现 View Controller (如 @buzzert 所建议),但是问题仍然存在。
最佳答案
这是因为呈现 View Controller (ViewController
) 是您的 ModalViewController
响应链中的 nextResponder
。
这是因为操作系统需要某种方式来从当前显示在屏幕上的 View Controller 一直追溯到应用程序。
如果您的呈现 View Controller 只有当它是第一响应者时才有意义的命令,解决这个问题的最简单方法是简单地覆盖 ViewController
上的 canPerformAction(_:)
>,如果不是第一响应者则返回false
。
例如,
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if self.isFirstResponder {
return super.canPerformAction(action, withSender: sender)
} else {
return false
}
}
否则,如果你想更多地控制响应链中的 nextResponder
,你也可以覆盖 nextResponder
getter 以“跳过”你的呈现 View Controller 。虽然不推荐这样做,但可以作为其工作原理的说明。
关于ios - View Controller 的键命令在模态显示时包含在内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61664793/