How to raise a UITextField when the keyboard shows

Paul Wallace
4 min readFeb 23, 2018

--

Solution:

Solution for updating UI based on keyboard appearance. Inspired by answers from https://stackoverflow.com/questions/26070242/move-view-with-keyboard-using-swift

The Rest of the Post:

Raising a UIView, or one of it’s many subclasses*, when the keyboard pops up is one of the most common issues beginners face when building their own app. There are dozens of Stack Overflow posts and hundreds of comments on each of those posts all trying to answer this simple problem. Even for veterans reading through all the possible ways to do this is a little mind numbing and especially for a beginners it can be difficult to filter through all the possible answers and choose for themselves what might be the best solution. Furthermore even if someone chooses a certain solution they often don’t understand exactly what’s happening underneath the hood or why that solution is good or bad. This prevents people from learning quickly and possibly causes them to pick up bad habits.

Here I’ll try to give a solution, the thought process behind it and explain, in depth, why I did it this way.

Let’s get started.

Your first reaction when developing something that you’re not sure about in iOS should be to refer to Apple documentation. You’ll usually find a plethora of useful information (as long as you read carefully!).

Here’s a little tidbit I found looking through the documentation for UITextField under the Responding to Keyboard-Related Notifications section:

“ Because the system manages the showing and hiding of the keyboard in response to responder changes, it posts the following notifications for tracking the keyboard-related changes”

These notifications are:

  1. UIKeyboardWillShow
  2. UIKeyboardDidShow
  3. UIKeyboardWillHide
  4. UIKeyboardDidHide
  5. UIKeyboardWillChangeFrame
  6. UIKeyboardDidChangeFrame

Okay, great — so there are these notifications of when the keyboard is going to do stuff. But how do we receive these notifications?

In iOS we use the NSNotificationCenter (or NotificationCenter if you’re using Swift) to send or receive notifications throughout our application. If you don’t know too much about Notifications in iOS then check back soon for my Notifications blog post coming out soon.

In terms of starting research, we pretty much have what we need! We want to listen for these notifications to be posted and when received we can adjust our UI so that everything looks good.

Let’s code.

  1. Create a new project (name it anything)
  2. Open up the storyboard file and use auto layout to pin a UITextField to the bottom of the view controller.
  • Add a leading constraint so we define an x value
  • Add a trailing constraint so we define a width
  • Add a bottom constraint so we define a y value

If we run the app now and press the text field the keyboard will show up and cover the text field. So let’s fix that now.

3. In ViewController.swift add the following code to the viewDidLoad function:

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
  • Here we are registering our view controller with the default notification center so that we can be updated whenever the keyboard will show or hide. You’ll noticed that for selectors I used functions that don’t exist yet in our file — so lets write them out now.

4. Add the following function headers to ViewController.swift:

@objc func keyboardWillShow(notification: NSNotification) {}
@objc func keyboardWillHide(notification: NSNotification) {}

5. Now we need to get the information of how large the keyboard will be after it updates. This information is available through the passed in NSNotification parameters userInfo object. The userInfo object is an optional so we need to unwrap it first to verify that it exists:

guard let userInfo = notification.userInfo else {return}

6. In order to get the size of the keyboard we need to access the userInfo dictionary with the key: UIKeyboardFrameEndUserInfoKey. We could also use the UIKeyboardFrameBeginUserInfoKey although it seems to be less consistent.

guard let keyboardSize = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else {return}

You might wonder how you were supposed to know to access the dictionary with that key specifically. When dealing with userInfo dictionary api’s from apple its generally a good idea to look up userInfo dictionary + the thing you’re dealing with. Here we’re dealing with the keyboard so we can search:

User Info Keyboard and we’ll find the corresponding apple documentation: https://developer.apple.com/documentation/uikit/uiwindow/keyboard_notification_user_info_keys

7. Since the value given to us from the dictionary comes as an NSValue it is not immediately useful to us. This NSValue encapsulate the info that we need and to access it we can use the NSValue property: cgRectValue.

let keyboardFrame = keyboardSize.cgRectValue

8. Now we can adjust our UI to fit the height of the keyboard. There are a ton of ways to adjust the UI — we can update the bottom constraint constant, we can put our textfield on a scroll view and adjust the scroll offset, we can even just move the view controller view up or change it’s bounds. For now we will just move the view controller’s view up.

if self.view.frame.origin.y == 0{                       self.view.frame.origin.y -= keyboardFrame.height         
}

9. And for keyboardWillHide we can set the origin.y back to 0:

if self.view.frame.origin.y != 0{                       self.view.frame.origin.y += keyboardFrame.height         
}

And that’s it! We have a working solution that can easily be adapted to other solutions. It should be noted that Apple gives a thorough example of how to use a scroll view to effectively accomplish the same goal: https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html#//apple_ref/doc/uid/TP40009542-CH5-SW1

Often times though, you don’t need a scroll view, in which case you can use the solution above.

Thanks for reading! Let me know if there’re any topics I can cover that you’d be interested in learning about.

*UITextField actually inherits from UIControl, and UIControl inherits from UIView

--

--