Move view with keyboard using swift 3

2019-08-23 03:20发布

I have an app that has a text field on the lower half of the view and I have a navigation controller bottom of page.

How would I go about moving the view upwards while typing so I can see what i'm typing and then moving it back down to its original place when the keyboard disappears? I don't want to move navigation controller

1条回答
爷的心禁止访问
2楼-- · 2019-08-23 03:38

You have to observe changes in keyboard frame and act accordingly to show your uiview (uitextfield, uitextview etc.) above the keyboard.

NotificationCenter Apple documentation: https://developer.apple.com/documentation/foundation/notificationcenter

Other answers at StackOverflow: How to make a UITextField move up when keyboard is present?

Here is a quick example of a view controller:

import UIKit

class ExampleViewController: UIViewController {

  // MARK: - Properties

  @IBOutlet weak var exampleTextView1: UITextView!
  @IBOutlet weak var exampleTextView2: UITextView!

  @IBOutlet weak var exampleTextView1BottomConstraint: NSLayoutConstraint!
  @IBOutlet weak var exampleTextView2BottomConstraint: NSLayoutConstraint!

  var exampleTextView1BottomConstraintInitialConstant: CGFloat!
  var exampleTextView2BottomConstraintInitialConstant: CGFloat!

  var keyboardVisibilityObservers: [NSObjectProtocol] = []

  // MARK: - View lifecycle

  override func viewDidLoad() {
    super.viewDidLoad()

    exampleTextView1BottomConstraintInitialConstant = exampleTextView1BottomConstraint.constant
    exampleTextView2BottomConstraintInitialConstant = exampleTextView2BottomConstraint.constant
  }

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Add observers for text view 1
    keyboardVisibilityObservers.append(createShowKeyboardObserver(keyboardTrigger: exampleTextView1, distance: 10.0, constraint: exampleTextView1BottomConstraint))
    keyboardVisibilityObservers.append(createHideKeyboardObserver(keyboardTrigger: exampleTextView1, constraint: exampleTextView1BottomConstraint, initialConstraintConstant: exampleTextView1BottomConstraintInitialConstant))


    // Add observers for text view 2
    keyboardVisibilityObservers.append(createShowKeyboardObserver(keyboardTrigger: exampleTextView2, distance: 10.0, constraint: exampleTextView2BottomConstraint))
    keyboardVisibilityObservers.append(createHideKeyboardObserver(keyboardTrigger: exampleTextView2, constraint: exampleTextView2BottomConstraint, initialConstraintConstant: exampleTextView2BottomConstraintInitialConstant))

  }

  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    removeAllKeyboardVisibilityNotificationObservers()
  }

  // MARK: - Keyboard event handling

  private func createShowKeyboardObserver(keyboardTrigger: UIView, distance: CGFloat, constraint: NSLayoutConstraint) -> NSObjectProtocol {
    return NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil) { (notification) in

      if let userInfo = notification.userInfo,
        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {

        // Get animation duration and curve from user info dictionary
        let duration: TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
        let animationCurve: UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

        let originYAxisOfKeyboardTrigger = keyboardTrigger.convert(keyboardTrigger.bounds.origin, to: self.view).y
        let preferredOriginYAxisOfKeyboardTrigger = endFrame.origin.y - distance - keyboardTrigger.bounds.height

        constraint.constant = constraint.constant - (originYAxisOfKeyboardTrigger - preferredOriginYAxisOfKeyboardTrigger)

        // Animate changes
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: { self.view.layoutIfNeeded() },
                       completion: nil)
      }
    }
  }

  private func createHideKeyboardObserver(keyboardTrigger: UIView, constraint: NSLayoutConstraint, initialConstraintConstant: CGFloat) -> NSObjectProtocol {
    return NotificationCenter.default.addObserver(forName: .UIKeyboardWillHide, object: nil, queue: nil) { (notification) in

      if let userInfo = notification.userInfo {

        // Get animation duration and curve from user info dictionary
        let duration: TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
        let animationCurve: UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

        constraint.constant = initialConstraintConstant

        // Animate changes
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: { self.view.layoutIfNeeded() },
                       completion: nil)
      }
    }
  }

  private func removeAllKeyboardVisibilityNotificationObservers() {
    keyboardVisibilityObservers.forEach { (observer) in
      NotificationCenter.default.removeObserver(observer)
    }

    keyboardVisibilityObservers.removeAll()
  }

}
查看更多
登录 后发表回答