How we can get is keyboard is shown or hidden currently in our app?
Keyboard is shown
That is it. Simple solution, we just need to add observer for keyboard notification.
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardShow),
name: Notification.Name.UIKeyboardWillShow, object: nil)
}
@objc func handleKeyboardShow(notification: Notification) {
print("Keyboard will show")
}
This observer only works for event when keyboard will be shown, there is another observer for event when keyboard will be hidden.
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardShow),
name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardHide),
name: Notification.Name.UIKeyboardWillHide, object: nil)
}
@objc func handleKeyboardShow(notification: Notification) {
print("Keyboard will show")
}
@objc func handleKeyboardHide(notification: Notification) {
print("Keyboard will hide")
}
But there is a lot more thing beside this. And I want to tell you about some of them.
For easily hide keyboard we can override this method in View Controller.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
Also, when we work with observers we should remove them when we don't need them anymore. It is need to be remove because we don't need to receive events when we leave current controller. In method
viewDidDisappear we remove observer. And we moving adding of observers from viewDidLoad to viewDidAppear. Because when we return to current View Controller again we need observers to be worked.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardShow),
name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardHide),
name: Notification.Name.UIKeyboardWillHide, object: nil)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
Getting Keyboard Frame
In notification, that will be sent to observer selector, contain information about keyboard frame. We can get this frame using following way.
@objc func handleKeyboardShow(notification: Notification) {
print("Keyboard will show")
if let userInfo = notification.userInfo {
if let keyboardFrameValue = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue) {
let keyboardFrame = keyboardFrameValue.cgRectValue
print(keyboardFrame)
// (0.0, 465.0, 414.0, 271.0)
}
}
}
There is the same code for getting keyboard frame when keyboard shown and hidden. So we can move it to separate method and invoke it from corresponding listeners.
@objc func handleKeyboardShow(notification: Notification) {
print("Keyboard will show")
handleKeyboardMoving(isVisible: true, notification: notification)
}
@objc func handleKeyboardHide(notification: Notification) {
print("Keyboard will hide")
handleKeyboardMoving(isVisible: false, notification: notification)
}
func handleKeyboardMoving(isVisible: Bool, notification: Notification) {
if let userInfo = notification.userInfo {
if let keyboardFrameValue = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue) {
let keyboardFrame = keyboardFrameValue.cgRectValue
print(keyboardFrame)
}
}
}
As we can see when keyboard is shown keyboard frame has less Y coordinate then keyboard is hidden.
Keyboard will show
(0.0, 465.0, 414.0, 271.0)
Keyboard will hide
(0.0, 736.0, 414.0, 271.0)
Keyboard Visibility as Global Property in AppDelegate
If we want to know anywhere in our app whether keyboard shown or hidden we need to create global variable for this purpose. We can make it in AppDelegate class. So, now AppDelegate is observer for visibility state of keyboard.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var isVisible = false
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
NotificationCenter.default.addObserver(self, selector: #selector(handleShow),
name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleHide),
name: NSNotification.Name.UIKeyboardWillHide, object: nil)
return true
}
@objc func handleShow()
{
isVisible = true
}
@objc func handleHide()
{
isVisible = false
}
}
Now in View Controller we can get AppDelegate instance of our application and get
isVisible property of it.
let status = (UIApplication.shared.delegate as! AppDelegate).isVisible
keyboardStatusLabel.text = "\(status)"
Keyboard is hidden and visible status is false
Keyboard is shown and visible status is true
Keyboard Visibility Listener as Singleton Class
We can create Singleton Class (only one instance of this Class will exist). There are a special methods: start and stop. In start method this class will add self as observer for showing and hiding keyboard. In stop it will remove itself from observing. When visibility of keyboard is changed then instance variable
isVisible will be updated(it has value false when initialized).
import Foundation
class KeyboardStateListener {
static let shared = KeyboardStateListener()
var isVisible = false
func start() {
NotificationCenter.default.addObserver(self, selector: #selector(handleShow),
name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleHide),
name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
@objc func handleShow()
{
isVisible = true
}
@objc func handleHide()
{
isVisible = false
}
func stop() {
NotificationCenter.default.removeObserver(self)
}
}
We need to start this this listener in AppDelegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
KeyboardStateListener.shared.start()
return true
}
Now we can use it anywhere in our app and get the current state of the keyboard
keyboardStatusLabel.text = "\(KeyboardStateListener.shared.isVisible)"
GitHub Source Code
There is source code for this project on
github
There are many articles circulating on internet that exaggerate about Custom Designed Websites. But your article is an exception that made me understand it without any difficulty.
ReplyDeleteThank you for sharing this important and useful information in this article. Best Custom Websites
ReplyDeleteThank you Sir, you made it easy as pie. Now i am able to understand and have enough knowledge about this. It is only because of you.
ReplyDeleteCustom Designed Websites
This is a great article! Thank you very much. I really need these suggestions. An in-depth explanation is of great benefit. Incredibly inspiring to see how you write. Custom Website
ReplyDeleteThank you for sharing this important and useful information in this article. This is very helpful for us.
ReplyDeleteMobile Performance Meter Hack
This is an excellent article. Your essay is very easy to understand. Thank you for providing us with this useful information.
ReplyDeleteSEO Company NYC