旋转时更改自定义键盘的高度

changing height of a custom keyboard when rotating

我有一个由代码创建的自定义键盘,它是特定文本字段的独特输入视图。我在我的项目中实现了这个:

let keyboardContainerView = KBContainerView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height*0.5))
keyboardContainerView.addSubview(myKeyboardView)
textfield.inputView = keyboardContainerView

KBContainerView是一个UIView但是有一个功能,就是当检测到设备旋转时,frame改变。很简单。

override init(frame: CGRect) {
    super.init(frame: frame)
    NotificationCenter.default.addObserver(self, selector: #selector(updateFrame), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}
    
@objc func updateFrame() {
    self.frame = CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height*0.5)
}

但我发现虽然键盘容器视图发生了变化,但正如我在命令行上打印的那样,但键盘的大小似乎没有变化。这是一张动图。

从横向视图开始也不会改变高度。

为了解决这个问题,我尝试在输入视图上使用 autoresizingMasks,但情况变得更糟,启动应用程序时键盘高度错误。导航栏还覆盖了横向视图中的键盘。

在我的项目中,为了简单起见,我没有写一个UIKeyboardviewController。我想要实现的是,当旋转我的设备时,键盘可以 占据屏幕的一半 space。 (高度为0.5 *屏幕高度)

是不是我把改变大小的动作写错了?

通常我使用

自定义inputView的标准键盘尺寸
autoresizingMask = [.flexibleWidth, .flexibleHeight]

在这种情况下,如果您希望它始终为高度的 50%,则可能需要

  • 关闭 translatesAutoresizingMaskIntoConstraints;
  • 为宽度、高度、centerX 和 bottom 添加您自己的约束

例如,下面是一个简单的输入视图,我将其定义为 window 高度的 50%,在键盘输入 UIView 子类中具有以下内容:

override func didMoveToSuperview() {
    super.didMoveToSuperview()
    
    translatesAutoresizingMaskIntoConstraints = false

    guard let superview = superview else { return }
    
    var lastView: UIView! = self
    while lastView.superview != nil {
        lastView = lastView.superview
    }

    NSLayoutConstraint.activate([
        heightAnchor.constraint(equalTo: lastView.heightAnchor, multiplier: 0.5, constant: 0),
        widthAnchor.constraint(equalTo: superview.widthAnchor),
        centerXAnchor.constraint(equalTo: superview.centerXAnchor),
        bottomAnchor.constraint(equalTo: superview.bottomAnchor)
    ])
}

现在我正在向上爬取视图层次结构以获取顶级视图。也许您想将您希望它用于高度约束的视图传递给它。我只是讨厌提到 UIScreen.main,因为有时我们的应用程序不会全屏显示。

但我们不要迷失在细节中。关键是使用约束,让自动布局引擎为我们做一切。那我们就不用自己去响应轮转事件了: