ios – 当中间的viewController包含两个viewController时,UIKeyCommands不起作用

我相信这是一个与UIKeyCommands相关的不平凡的问题,ViewController和/或响应者的层次结构.

在我的iOS 9.2应用程序中,我有一个名为NiceViewController的类,定义了UIKeyCommand,导致打印到控制台.

这是NiceViewController:

class NiceViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()

    let command = UIKeyCommand(input: "1",modifierFlags:UIKeyModifierFlags(),action: #selector(keyPressed),discoverabilityTitle: "nice")

    addKeyCommand(command)
  }

  func keyPressed() {
    print("works")
  }
}

当我添加NiceViewController作为唯一的孩子,我的主视图控制器都可以正常工作 – 在外部键盘上按下“1”(物理键盘在模拟器中使用时)的作用就像一个魅力.但是,当我向主视图控制器添加第二个视图控制器时,NiceViewController中定义的UIKeyCommands停止工作.

我很想明白为什么会发生这种情况,以及如何确保在我的主视图控制器中有多个子视图控制器不会阻止这些子视图控制器处理UIKeyCommands.

这是我的主视图控制器:

class MainViewController: UIViewController {
  let niceViewController = NiceViewController()
  let normalViewController = UIViewController()

  override func viewDidLoad() {
    super.viewDidLoad()


    self.view.addSubview(niceViewController.view)
    self.addChildViewController(niceViewController)

    self.view.addSubview(normalViewController.view)
    // removing below line makes niceViewController accept key commands - why and how to fix it?
    self.addChildViewController(normalViewController)

  }
}

解决方法

我不相信这是UIKeyCommands的问题

在iOS中,一次只能有一个View Controller可以管理关键命令.所以随着你的设置,你有一个容器视图控制器与几个子视图控制器.您应该告诉iOS,您希望NiceViewController控制关键命令.

定义首要响应者

在高层次上,为了支持关键命令,您不仅必须创建一个UIKeyCommand并将其添加到视图控制器,而且还必须使您的视图控制器成为第一个响应者,以便能够响应键命令.

首先,在任何希望使用关键命令的控制器中,您应该让iOS知道该控制器能够成为第一响应者:

override func canBecomeFirstResponder() -> Bool {
    // some conditional logic if you wish
    return true
}

接下来,您需要确保VC确实成为第一个响应者.如果任何VC包含成为响应者(或类似的)的某些文本字段,则该VC可能会自己成为第一个响应者,但您可以随时在NiceViewController上调用wasFirstResponder(),使其成为第一个响应者,并且在其他的事情,响应关键命令.

请参阅UIKeyCommand的文档:

The system always has the first opportunity to handle key commands. Key commands that map to known system events (such as cut,copy and paste) are automatically routed to the appropriate responder methods. For other key commands,UIKit looks for an object in the responder chain with a key command object that matches the pressed keys. If it finds such an object,it then walks the responder chain looking for the first object that implements the corresponding action method and calls the first one it finds.

注意:有人正在与其他VC进行互动,而且是第一个响应者,NiceViewController不能同时成为第一个响应者,因此您可能需要在其他VC上使用一些关键命令.

为什么这并不总是必要的

当只有一个VC被呈现时,iOS似乎假设它将是第一个响应者,但是当你有一个容器VC时,iOS似乎将容器视为第一个响应者,除非有一个孩子说它能够成为第一响应者.

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...