如何根据 phone 的边框在自动布局中为应用内键盘设置不同的位置?

How to set different position for in-app keyboard in autolayout depending on phone's bezels?

我正在尝试制作一个包含日语 iOS 键盘副本的应用程序。

我设法在界面生成器中重新创建了它。我已将键嵌入到它们自己的视图中,并且键的自动布局工作得很好。

我的问题是我希望键盘与系统键盘完全匹配。键盘视图在 iPhone 带边框的型号上应距底部 4 个像素,在 iPhone 的 X 系列机型上应距底部 80 像素,以说明它们没有边框。

我真的不想对基于 iPhone 模型的约束进行硬编码。定位键盘以适应这两种手机的最佳方式是什么?

有没有办法检测 iPhone 是否有边框?


唯一的区别是:

iPhoneX系列: bottom = KeyboardView.bottom + 80

其他:bottom = KeyboardView.bottom + 4

您应该使用 UIInputViewController 及其 inputView。 "keyboard"(输入视图)将自动出现在所有设备类型的正确位置。

以防其他人试图做同样的事情,我终于想通了。

我试图让我的视图控制器覆盖 canBecomeFirstResponder 到 return true 并调用 self.becomeFirstResponder() 调出键盘。 但是,由于视图控制器不是文本字段,因此它不会将键盘定位为文本键盘。如果您的自定义输入是 UIPickerView,这可能有效,但它不适用于文本键盘。您必须在 UITextField 上调用 becomeFirstResponder(),系统才能正确定位您的键盘。

另外,设置布局约束时,不能使用

keyboardView.bottomAnchor.constraint(equalTo: inputView.safeAreaLayoutGuide.bottomAnchor)])

甚至

keyboardView.bottomAnchor.constraint(equalTo: inputView.safeAreaLayoutGuide.bottomAnchor)])

这会将您的键盘固定在底部,并且不会在其下方留出足够的空间。


这是我的解决方案:

class KeyboardViewController: UIInputViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    let nib = UINib(nibName: "KeyboardView", bundle: nil)
    let keyboardView = nib.instantiate(withOwner: nil).first as! KeyboardView

    guard let inputView = self.inputView else { return }
    inputView.translatesAutoresizingMaskIntoConstraints = false
    inputView.addSubview(keyboardView)

    keyboardView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      keyboardView.leftAnchor.constraint(equalTo: inputView.leftAnchor),
      keyboardView.topAnchor.constraint(equalTo: inputView.topAnchor),
      keyboardView.rightAnchor.constraint(equalTo: inputView.rightAnchor)])
  } 
}

对于我的视图控制器,我只是这样做:

  let keyboardViewController = KeyboardViewController()

  override func viewDidLoad() {
    super.viewDidLoad()

    textField.inputView = self.keyboardViewController.inputView
    textField.becomeFirstResponder()
  }

如果您有任何建议,或者知道如何在不调用文本字段 becomeFirstResponder() 的情况下调出键盘,请告诉我。

希望这会帮助到一些人。