当中间viewController包含两个viewControllers时,UIKeyCommands不起作用

mga*_*mer 11 uiviewcontroller first-responder becomefirstresponder ios swift

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

在我的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")
  }
}
Run Code Online (Sandbox Code Playgroud)

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

我很想知道它为什么会发生以及如何确保我的主视图控制器有多个子视图控制器不会阻止那些子视图控制器处理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)

  }
}    
Run Code Online (Sandbox Code Playgroud)

Mat*_*man 6

我不相信这是一个问题 UIKeyCommands

在 iOS 中,一次只有一个 View Controller 可以管理关键命令。因此,通过您的设置,您有一个带有几个子视图控制器的容器视图控制器。您应该告诉 iOS 您希望 NiceViewController 能够控制关键命令。

定义第一响应者

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

首先,在你想要使用键盘命令的任何视图控制器中,你应该让 iOS 知道该控制器能够成为第一响应者:

override func canBecomeFirstResponder() -> Bool {
    // some conditional logic if you wish
    return true
}
Run Code Online (Sandbox Code Playgroud)

接下来,您需要确保 VC 确实成为第一响应者。如果有任何风险投资包含某种形式的文本字段成为应答(或类似的东西),即VC可能会成为自己的第一个响应者,但你可以随时调用becomeFirstResponder()NiceViewController,使之成为第一个响应者,除其他事项外,响应到关键命令。

请参阅以下文档UIKeyCommand

系统总是有第一次机会来处理按键命令。映射到已知系统事件(例如剪切、复制和粘贴)的关键命令会自动路由到适当的响应程序方法。对于其他按键命令,UIKit 会在响应者链中寻找一个对象,该对象具有与按下的键匹配的按键命令对象。如果它找到这样一个对象,它就会在响应者链中寻找实现相应操作方法的第一个对象并调用它找到的第一个对象。

注意:当有人与另一个 VC 交互并且它是第一响应者时NiceViewController不能同时成为第一响应者,因此您可能还需要其他 VC 上的一些关键命令。

为什么这并不总是必要的

当只有一个 VC 出现时,iOS 似乎假设它会是第一响应者,但是当你有一个容器 VC 时,iOS 似乎将容器视为第一响应者,除非有一个孩子说它能够成为第一响应者急救人员。