Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting keyboard size from userInfo in Swift

I have been trying to add some code to move my view up when the keyboard appears, however, I am having issues trying to translate the Objective-C examples into Swift. I have made some progress, but I am stuck on one particular line.

These are the two tutorials/questions I have been following:

How to move content of UIViewController upwards as Keypad appears using Swift http://www.ioscreator.com/tutorials/move-view-when-keyboard-appears

Here is the code I currently have:

override func viewWillAppear(animated: Bool) {     NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)     NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil) }  override func viewWillDisappear(animated: Bool) {     NSNotificationCenter.defaultCenter().removeObserver(self) }  func keyboardWillShow(notification: NSNotification) {     var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))     UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)     let frame = self.budgetEntryView.frame     frame.origin.y = frame.origin.y - keyboardSize     self.budgetEntryView.frame = frame }  func keyboardWillHide(notification: NSNotification) {     // } 

At the moment, I am getting an error on this line:

var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey)) 

If someone could let me know what this line of code should be, I should manage to figure out the rest myself.

like image 533
user3746428 Avatar asked Aug 22 '14 15:08

user3746428


People also ask

What is the height of keyboard in IOS?

The top of the keyboard needs to be about 2 inches from the bottom of the *device* as it is held. Prior to the iPhone X, this is easy because all devices used the exact same bezel insets, so it's 216 pts from the bottom of the screen.

How do you dismiss a keyboard in Swift?

Via Tap Gesture This is the quickest way to implement keyboard dismissal. Just set a Tap gesture on the main View and hook that gesture with a function which calls view. endEditing . Causes the view (or one of its embedded text fields) to resign the first responder status.


2 Answers

There are some problems in your line:

var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey)) 
  • notification.userInfo returns an optional dictionary [NSObject : AnyObject]?, so it must be unwrapped before accessing its values.
  • The Objective-C NSDictionary is mapped to a Swift native Dictionary, so you must use the dictionary subscript syntax (dict[key]) to access the values.
  • The value must be cast to NSValue so that you can call CGRectValue on it.

All this can be achieved with a combination of optional assignment, optional chaining and optional casts:

if let userInfo = notification.userInfo {    if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {     let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)        // ...    } else {        // no UIKeyboardFrameBeginUserInfoKey entry in userInfo    } } else {    // no userInfo dictionary in notification } 

Or in one step:

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {     let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)     // ... } 

Update for Swift 3.0.1 (Xcode 8.1):

if let userInfo = notification.userInfo {     if let keyboardSize = userInfo[UIKeyboardFrameBeginUserInfoKey] as? CGRect {         let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)         // ...     } else {         // no UIKeyboardFrameBeginUserInfoKey entry in userInfo     } } else {     // no userInfo dictionary in notification } 

Or in one step:

if let keyboardSize = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? CGRect {     let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)     // ... } 

Update for Swift 5 (Xcode 11.6):

 guard let userInfo = notification.userInfo,               let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } 

I recommend using keyboardFrameEndUserInfoKey instead of keyboardFrameBeginUserInfoKey since the keyboard changes the initial render height after the first display on older iOS devices.

like image 183
Martin R Avatar answered Oct 28 '22 00:10

Martin R


For even less code consider looking at THIS

It was really helpful to me. You just have to include the view constraint in the view controller and using the two observers you added. Then just use the following methods (it is supposed here you move a tableView)

func keyboardWillShow(sender: NSNotification) {         if let userInfo = sender.userInfo {             if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height {                 tableViewBottomConstraint.constant = keyboardHeight                 UIView.animateWithDuration(0.25, animations: { () -> Void in                     self.view.layoutIfNeeded()                 })             }         }     } 

and

func keyboardWillHide(sender: NSNotification) { if let userInfo = sender.userInfo {   if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height {     tableViewBottomConstraint.constant = 0.0     UIView.animateWithDuration(0.25, animations: { () -> Void in self.view.layoutIfNeeded() })   } } } 
like image 25
Nicholas Avatar answered Oct 28 '22 00:10

Nicholas