Swift 中键盘出现时移动文本字段


在真实的 iOS 应用程序中,大多数情况下您会使用 UITextFields 来获取各种输入。为了在编辑时使文本字段可见,您可以通过更新约束来管理它们。要管理约束,您必须为键盘显示和隐藏添加观察者。

在本文中,我们将通过以下步骤在键盘出现时移动文本字段。

步骤 1 - 基本设置

在此步骤中,我们将通过添加一个文本字段来输入电子邮件地址进行一些基本设置。我们将文本字段添加到屏幕底部,以便在键盘出现时可以移动它。

示例

import UIKit
class TestController: UIViewController {

   private lazy var emailTextField: UITextField = {
      let textField = UITextField()
      textField.keyboardType = .emailAddress
      textField.layer.cornerRadius = 8
      textField.layer.masksToBounds = true
      textField.layer.borderWidth = 1.0
      textField.layer.borderColor = UIColor(white: 0, alpha: 0.3).cgColor
      textField.placeholder = "Email Address"
      textField.textAlignment = .center
      textField.autocorrectionType = .no
      textField.delegate = self
      return textField
   }()
  
   private var textFieldBottomConstraint: NSLayoutConstraint?
   override func viewDidLoad() {
      super.viewDidLoad()
      initialSetup()
   }
   
   override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)

      // adding notification observers for keyboard show and hide
      NotificationCenter.default.addObserver(self,
      selector: #selector(keyboardWillShow),
      name: UIResponder.keyboardWillShowNotification,
      object: nil)
     
      NotificationCenter.default.addObserver(self,
      selector: #selector(self.keyboardWillHide),
      name: UIResponder.keyboardWillHideNotification,
      object: nil)
   }
   
   override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
     
      // removing all the notification observers
      NotificationCenter.default.removeObserver(self)
   }
   
   private func initialSetup() {
   
      // basic setup
      view.backgroundColor = .white
      navigationItem.title = "UITextField"
    
      // adding constraints to emailTextField
      view.addSubview(emailTextField)
      emailTextField.translatesAutoresizingMaskIntoConstraints = false
      emailTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30).isActive = true
      emailTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30).isActive = true
      emailTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
      textFieldBottomConstraint = emailTextField.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -100)
      textFieldBottomConstraint?.isActive = true
   }
   
   @objc private func keyboardWillShow(_ notification: NSNotification) {
   
      // write code to complete the implementation
   }
   
   @objc private func keyboardWillHide(_ notification: NSNotification) {
   
      // write code to complete the implementation
   }
   
   func updateViewWithKeyboard(notification: NSNotification,
   viewBottomConstraint: NSLayoutConstraint,
   keyboardWillShow: Bool) {
   
      // write code to complete the implementation
   }
}

输出

在上面的代码中,我们做了以下事情:

  • 向视图添加了一个电子邮件文本字段,并设置了一些约束。

  • 声明了一个变量“textFieldBottomConstraint”来保存对电子邮件文本字段底部约束的引用。

  • 现在键盘显示和隐藏的通知观察者可用。在 viewWillAppear 方法中添加了这些观察者。

  • 在 viewWillDisappear 中移除通知观察者,以避免不必要的​​方法调用。

步骤 2 - 完成 keyboardWillShow 和 keyboardWillHide 方法的实现

在此步骤中,我们将完成这两种方法的代码。以下是这两种方法的完整代码。

@objc private func keyboardWillShow(_ notification: NSNotification) {
   
   // move the text field when the email text field is being edited
   if emailTextField.isEditing {
      updateViewWithKeyboard(notification: notification,
      viewBottomConstraint: self.textFieldBottomConstraint!,
      keyboardWillShow: true)
   }
}
@objc private func keyboardWillHide(_ notification: NSNotification) {

   // move the field back to the previous position after editing is done
   updateViewWithKeyboard(notification: notification,
   viewBottomConstraint: self.textFieldBottomConstraint!,
   keyboardWillShow: false)
}

步骤 3 - 完成 updateViewWithKeyboard 方法的实现

我们将完成 updateViewWithKeyboard 方法的代码,以支持键盘移动并返回到以前的位置。代码如下。

private func updateViewWithKeyboard(notification: NSNotification,
viewBottomConstraint: NSLayoutConstraint,
keyboardWillShow: Bool) {

   // getting keyboard size
   guard let userInfo = notification.userInfo,
   let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
      return
   }

   // getting duration for keyboard animation
   guard let keyboardDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
      return
   }

   // getting keyboard animation's curve
   guard let keyboardCurve = UIView.AnimationCurve(rawValue: userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as! Int) else {
      return
   }

   // getting keyboard height
   let keyboardHeight = keyboardSize.cgRectValue.height

   // setting constant for keyboard show and hide
   if keyboardWillShow {
      viewBottomConstraint.constant = -(keyboardHeight + 50)
   } else {
      viewBottomConstraint.constant = -100
   }

   // animate the view the same way the keyboard animates
   let animator = UIViewPropertyAnimator(duration: keyboardDuration, curve: keyboardCurve) {
      [weak self] in self?.view.layoutIfNeeded()
   }

   // perform the animation
   animator.startAnimation()
}

在上面的代码中,我们做了以下事情:

  • 从通知对象提供的用户信息中获取键盘大小。

  • 从用户信息对象中获取键盘动画的持续时间。

  • 从用户信息对象中获取键盘动画的动画类型。

  • 获取键盘高度并更改 viewBottomConstraint 对象的常量值。

  • 通过执行 startAnimation 方法使用 UIViewPropertyAnimator 类为视图设置动画。

输出

步骤 4 - 实现 UITextFieldDelegate 方法

在此步骤中,我们将实现委托方法,通过点击 Return 按钮来隐藏键盘。代码如下。

extension TestController: UITextFieldDelegate {
    
   func textFieldShouldReturn(_ textField: UITextField) -> Bool {
      textField.resignFirstResponder()
   }
}

结论

要接收键盘出现和消失时的键盘通知,您可以使用键盘通知观察者。您可以从在通知对象中接收的 userInfo 对象中获取键盘高度以及其他值。获取键盘高度后,您可以使用 constant 属性更新约束值。

更新于: 2023-03-27

2K+ 次查看

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告