Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move textfield when keyboard appears swift

I'm using Swift for programing with iOS and I'm using this code to move the UITextField, but it does not work. I call the function keyboardWillShow correctly, but the textfield doesn't move. I'm using autolayout.

override func viewDidLoad() {     super.viewDidLoad()     NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);     NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil); }  deinit {     NSNotificationCenter.defaultCenter().removeObserver(self); }  func keyboardWillShow(notification: NSNotification) {     if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {         //let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)          var frame = self.ChatField.frame         frame.origin.y = frame.origin.y - keyboardSize.height + 167         self.chatField.frame = frame         println("asdasd")     } } 
like image 782
Pedro Manfredi Avatar asked Sep 05 '14 19:09

Pedro Manfredi


2 Answers

There are a couple of improvements to be made on the existing answers.

Firstly the UIKeyboardWillChangeFrameNotification is probably the best notification as it handles changes that aren't just show/hide but changes due to keyboard changes (language, using 3rd party keyboards etc.) and rotations too (but note comment below indicating the keyboard will hide should also be handled to support hardware keyboard connection).

Secondly the animation parameters can be pulled from the notification to ensure that animations are properly together.

There are probably options to clean up this code a bit more especially if you are comfortable with force unwrapping the dictionary code.

 class MyViewController: UIViewController {     // This constraint ties an element at zero points from the bottom layout guide    @IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint?      override func viewDidLoad() {      super.viewDidLoad()      NotificationCenter.default.addObserver(self,        selector: #selector(self.keyboardNotification(notification:)),        name: UIResponder.keyboardWillChangeFrameNotification,        object: nil)    }      deinit {      NotificationCenter.default.removeObserver(self)    }      @objc func keyboardNotification(notification: NSNotification) {      guard let userInfo = notification.userInfo else { return }       let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue      let endFrameY = endFrame?.origin.y ?? 0      let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0      let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber      let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue      let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)       if endFrameY >= UIScreen.main.bounds.size.height {        self.keyboardHeightLayoutConstraint?.constant = 0.0      } else {        self.keyboardHeightLayoutConstraint?.constant = endFrame?.size.height ?? 0.0      }       UIView.animate(        withDuration: duration,        delay: TimeInterval(0),        options: animationCurve,        animations: { self.view.layoutIfNeeded() },        completion: nil)    } } 
like image 138
Joseph Lord Avatar answered Sep 23 '22 12:09

Joseph Lord


If you're using Auto Layout, I assume you've set the Bottom Space to Superview constraint. If that's the case, you simply have to update the constraint's value. Here's how you do it with a little bit of animation.

func keyboardWasShown(notification: NSNotification) {     let info = notification.userInfo!     let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()      UIView.animateWithDuration(0.1, animations: { () -> Void in         self.bottomConstraint.constant = keyboardFrame.size.height + 20     }) } 

The hardcoded 20 is added only to pop the textfield above the keyboard just a bit. Otherwise the keyboard's top margin and textfield's bottom margin would be touching.

When the keyboard is dismissed, reset the constraint's value to its original one.

like image 32
Isuru Avatar answered Sep 26 '22 12:09

Isuru