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+ 次檢視

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.