为UIKeyboard提升UIViews

时间:2018-10-25 19:50:38

标签: swift uikeyboard nsnotifications

我为键盘添加了willShow和willHide观察器,并试图向上推底部的UITextView以适应显示的UIKeyboard。但是,我的键盘被推到的高度不仅仅是键盘框架的高度。如何将UITextView底部锚点限制在键盘顶部?

// Observer method
@objc func handleKeyboardNotification(_ notification: NSNotification) {
    if let userInfo = notification.userInfo {
        let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
        let isKeyboardShowing = (notification.name == UIResponder.keyboardWillShowNotification)

        // Push views up if keyboard is showing, otherwise set constant back to 0
        messageInputBottomAnchor?.constant = isKeyboardShowing ? -(keyboardFrame?.height)! : 0

        UIView.animate(withDuration: 0.5) {
            self.view.layoutIfNeeded()
        }
    }
}

Picture illustrating the problem

2 个答案:

答案 0 :(得分:1)

我所做的是

  • 我在UITextView上创建了2种不同的约束,一种是对超级视图的约束,另一种是对安全区域的约束。
  • 将这两个约束都连接到视图控制器,并确保它们不是弱引用。
  • viewDidLoad中,确保安全区域约束处于活动状态,而超级视图约束未处于活动状态。
  • 在听众中,当键盘抬起时,切换约束的isActive字段,这样,超级视图1处于活动状态,安全区域处于非活动状态。
  • 要在监听器中辞职时,将其切换回去。

需要确保引用不是weak的原因是,当您将isActive字段设置为false时,它将实际上将其删除,如果您尝试并在以后引用约束,您将发现自己尝试访问nil对象的成员。

答案 1 :(得分:0)

我将UITextView限制在safeAreaLayoutGuide的底部,但是我添加了一个CGFloat来表示屏幕底部的填充。它默认为0,但是如果有iOS 11可用(考虑到iPhone X及其底部填充),我将CGFloat设置为UIApplication.shared.keyWindow!.safeAreaInsets.bottom。然后,当我根据UIKeyboard上下移动UITextView时,我减去了CGFloat的大小。

//Global var 
var safeAreaBottom: CGFloat = 0.0

// Verify screen bottom in viewDidLoad
if #available(iOS 11, *) {
   safeAreaBottom = UIApplication.shared.keyWindow!.safeAreaInsets.bottom
}

// Push views up if keyboard is showing, otherwise set constant back to 0. Subtract safeAreaBottom if iOS 11 is available to compensate for the bottom padding
   textViewBottomAnchorToSafeArea?.constant = isKeyboardShowing ? -((keyboardFrame?.height)! - safeAreaBottom) : 0