Getting keyboard size from userInfo in Swift
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 callCGRectValue
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.
How to get height of Keyboard?
Swift
You can get the keyboard height by subscribing to the UIKeyboardWillShowNotification
notification. (Assuming you want to know what the height will be before it's shown).
Swift 4
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillShow),
name: UIResponder.keyboardWillShowNotification,
object: nil
)
@objc func keyboardWillShow(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
}
}
Swift 3
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillShow),
name: NSNotification.Name.UIKeyboardWillShow,
object: nil
)
@objc func keyboardWillShow(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
}
}
Swift 2
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
func keyboardWillShow(notification: NSNotification) {
let userInfo: NSDictionary = notification.userInfo!
let keyboardFrame: NSValue = userInfo.valueForKey(UIKeyboardFrameEndUserInfoKey) as! NSValue
let keyboardRectangle = keyboardFrame.CGRectValue()
let keyboardHeight = keyboardRectangle.height
}
How to reliably get keyboard height in iOS Swift?
don't know your exact scenario but try to use IQKeyboard it will deal with all your problems.
iOS 11 - Keyboard Height is returning 0 in keyboard notification
Use this:
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
For Swift, you can use:
let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
Why does Calculating keyboard size sometimes produces a zero height
Hardware Keyboard:
The notification indicates only the height of the keyboard shown on screen.
When a hardware keyboard is connected to the device, the keyboard need not be shown on the screen and hence the keyboard the keyboard height would be zero
Keyboard Height:
I would use UIKeyboardDidShow
notification and UIKeyboardFrameEndUserInfoKey
to get the keyboard frame (and subsequently the height)
@objc private func keyboardWasShown(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect else {
return
}
let keyboardHeight = endFrame.height
print("keyboardHeight = \(keyboardHeight)")
}
Get keyboard size with suggestion bar swift
You should be listening for changes in the keyboard's size and adjusting the rest of your content that way, since, as you found out, iOS keyboards can change size. You should subscribe to UIResponder.keyboardWillChangeFrameNotification
and/or UIResponder.keyboardDidChangeFrameNotification
which are notifications which trigger when the keyboard's frame will, or did, change. Here's an example of it in use:
// Somewhere in set up code
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidChangeFrame),
name: UIResponder.keyboardDidChangeFrameNotification, object: nil)
// Function elsewhere in your class
@objc func keyboardDidChangeFrame(_ notification: Notification) {
guard let kbSize = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey]
as? CGRect else {
return;
}
// Use kbRect as you initially did
}
Note that you can use either the Will
or the Did
notifications depending on how you want the layout change to look. You can also query both UIResponder.keyboardFrameBeginUserInfoKey
UIResponder.keyboardFrameEndUserInfoKey
to get the keyboard frame before and after the size change, which may be useful if you want to animate your layout along with the keyboard.
How to get actual keyboard height (keyboard height minus safe area insets)
First you have to get Safe Area bottom height and then
exclude it from keyboard total height. In this way you will get only
keyboard height without bottom safe area.
pesudo code:
let keyboardHeight = your keyboard height - bottomPadding
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
let bottomPadding = window?.safeAreaInsets.bottom
}
Hope it will help you.
Related Topics
How to Import a Swift File from Another Swift File
Uibezierpath: How to Add a Border Around a View With Rounded Corners
How to Return an Object That I Create in My Data Service Class Through Firebase
Fix Warning "C-Style For Statement Is Deprecated" in Swift 3
Is There a Swift Alternative For Nslog(@"%S", _Pretty_Function_)
Swift Structs to Nsdata and Back
Real Time Nstask Output to Nstextview With Swift
Why Is 'Nil' Not Compatible With 'Unsafepointer≪Cgaffinetransform≫' in Swift 3
How to Use Userdefaults With Swiftui
Swiftui 2: the Way to Open View in New Window
How to Get Text to Wrap in a Uilabel (Via Uiviewrepresentable) Without Having a Fixed Width
Swift Variable Name With ' (Backtick)
How Does One Make an Optional Closure in Swift
"Classname Has No Member Functionname" When Adding Uibutton Target
Difference Between 'Let' and 'Var' in Swift