Almost every app needs a way of inserting information using keyboard. When keyboard shows up, we do not want to keep content behind the keyboard hidden and instead, allow user to see it. UIResponder contains several notifications we can use to adjust the layout.
Keyboard change notifications
UIResponder contains a list of notifications and user info keys. We have notifications for reacting to visibility and frame changes (for example when rotating device). Notification’s userInfo contains a variety of information about the change. What makes this API a little bit difficult to use is parsing the user info every time we need to use those notifications. If we need to observe keyboard in several view controllers then the amount of code of setting up observation and doing type casting starts to build up. Therefore it makes more sense to have an object handling the observation and type casting user info keys.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
KeyboardObserver is a lightweight object observing keyboard related notifications and calling the changeHandler when any of the notifications is received. User info and notification type information is represented with struct Info. Before looking into how it is implemented, let’s take a look on the example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here we can see that setting up observer is straight-forward and accessing end frame of the keyboard does not require any type casting. Compare it with adding observers to those notifications and then using conditional casts for getting relevant information in the view controller.
Creating a KeyboardObserver
But let’s now take a look on how it is implemented and see how much less code we need to write in the future. KeyboardObserver is initialised with a changeHandler closure like seen in the previous paragraph. Initialiser retains the handler and sets up observers for all the relevant notifications. For simplicity, we are observing all the notifications but it would also be possible to have an extra argument defining a set of Events and then observing only the notifications we really want to react to.
Type casting relies completely on promises made by UIKit. As UIKit promises that user info always contains those values, we can avoid having any optional values in the Info struct. Therefore it is simpler to use the struct later on as no unwrapping is required.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We took a look on how to avoid observing multiple notifications and type casting notification user info values on the view controller level. Instead, we created a separate object handling observing and type casting and gives us a simple and concise API to work with.
One reply on “Observing keyboard visibility on iOS”
[…] wrote about keyboard notifications a while ago in “Observing keyboard visibility on iOS”. We’ll also create a class named KeyboardObserver and its responsibility is to observe […]
One reply on “Observing keyboard visibility on iOS”
[…] wrote about keyboard notifications a while ago in “Observing keyboard visibility on iOS”. We’ll also create a class named KeyboardObserver and its responsibility is to observe […]
LikeLike