使用swift 3使用键盘移动视图

时间:2017-09-10 10:26:20

标签: ios iphone swift swift3

我有一个应用程序,在视图的下半部分有一个文本字段,我的页面底部有一个导航控制器。

如何在打字时向上移动视图以便我可以看到我键入的内容,然后在键盘消失时将其移回原来的位置? 我不想移动导航控制器

1 个答案:

答案 0 :(得分:0)

您必须观察键盘框架的变化并采取相应措施,以便在键盘上方显示您的uiview(uitextfield,uitextview等)。

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

StackOverflow的其他答案:How to make a UITextField move up when keyboard is present?

以下是视图控制器的快速示例:

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()
  }

}