What is the animation speed of the keyboard appearing in iOS8?
Solution 1
You can get the animation duration and the animation curve from the userInfo dictionary on the keyboardWillShow: notifications.
First register for the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Then get the values from the notifications userInfo keys.
- (void)keyboardWillShow:(NSNotification*)notification {
NSNumber *duration = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [notification.userInfo objectForKey: UIKeyboardAnimationCurveUserInfoKey];
// Do stuff with these values.
}
There are a lot more of these keys, and you can also get them from the UIKeyboardWillDismiss notification.
This functionality is available all the way back to iOS 3.0 :D
Heres the docs:
Swift Version
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
@objc func keyboardWillShow(_ notification: Notification) {
let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey]
let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey]
}
Solution 2
The answer with the variable duration is right and work iOS 3 to 8, but with the new version of Swift, the answer's code is not working anymore. Maybe it is a mistake on my side, but I have to write:
let duration = aNotification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as Double
let curve = aNotification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as UInt
self.view.setNeedsLayout()
//baseConstraint.constant = 211
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions(curve), animations: { _ in
//self.view.layoutIfNeeded()
}, completion: { aaa in
//(value: Bool) in println()
})
Looks like objectForKey is not working anymore and conversion is more strict.
Solution 3
swift3
let duration = noti.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
let curve = noti.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
self.view.setNeedsLayout()
UIView.animate(withDuration: TimeInterval(duration), delay: 0, options: [UIViewAnimationOptions(rawValue: UInt(curve))], animations: {
self.view.layoutIfNeeded()
}, completion: nil)
Solution 4
Swift 4 update, iOS 11+
Register for the notification first in a view's lifecycle method :
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
}
Then in keyBoardWillShow
method :
@objc func keyBoardWillShow(notification: NSNotification) {
guard let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double else {return}
print(duration) // you got animation's duration safely unwraped as a double
}
Finally, don't forget to remove observer in deinit
method :
deinit {
NotificationCenter.default.removeObserver(self)
}
Solution 5
Firstly, the selected answer is the right way to go.
More can be provided here is what the animation really is. If you print all CAAnimations in the UIViewAnimation block, you'll find that it's a CASpringAnimation when setting the animation curve to the one provided in keyboard notification. The duration is 0.5, and other parameters are:
let ani = CASpringAnimation(keyPath: someKey)
ani.damping = 500
ani.stiffness = 1000
ani.mass = 3
ani.duration = 0.5
The code above can reproduce the animation precisely.
Once animation curve is set to the keyboard one, UIView animation will ignore the duration in the parameter. (If you really want to change the duration, adjust the mass
value.)
user3784622
Updated on August 04, 2020Comments
-
user3784622 over 3 years
The following is an animation for a textField and toolBar which move upward when the keyboard appears.
baseConstraint.constant = 211 self.view.setNeedsUpdateConstraints() UIView.animateWithDuration(0.30, animations: { self.view.layoutIfNeeded() })
It is close but not quite identical. How would you modify the above animation?
Edit:
Here is the final code using the answer below!
func keyboardWillShow(aNotification: NSNotification) { let duration = aNotification.userInfo.objectForKey(UIKeyboardAnimationDurationUserInfoKey) as Double let curve = aNotification.userInfo.objectForKey(UIKeyboardAnimationCurveUserInfoKey) as UInt self.view.setNeedsLayout() baseConstraint.constant = 211 self.view.setNeedsUpdateConstraints() UIView.animateWithDuration(duration, delay: 0, options: UIViewAnimationOptions.fromMask(curve), animations: { self.view.layoutIfNeeded() }, completion: { (value: Bool) in println() }) }
-
Steven Fisher almost 10 yearsYou might want to mention this works in iOS 7 (and earlier), too. :) I'm not sure if that's clear…
-
Joel Bell almost 10 yearsJust added it! Thanks :)
-
Joel Bell almost 10 yearsMake sure the notification your registering for is UIKeyboardWillShowNotification, not UIKeyboardDidShowNotification
-
pronebird over 9 yearsNote: You receive KeyboardWillShow event on "quicktype" view collapse/expand, curve and duration = 0 in that case. The size passed along with UIKeyboardFrameEndUserInfoKey key and is correct.
-
Thellimist about 9 yearsI tried these but still the animation doesn't work proper. I'm using self.view.frame = CGRectOffset(self.view.frame, 0, movement) instead of self.view.setNeedsLayout() self.view.setNeedsUpdateConstraints() does it matter?
-
Thellimist about 9 yearsI tried these but still the animation doesn't work proper. I'm using self.view.frame = CGRectOffset(self.view.frame, 0, movement) instead of self.view.setNeedsLayout() self.view.setNeedsUpdateConstraints() does it matter?
-
Dam about 9 yearsI do not understand where is your problem, but as now Swift is a clean code, I use it this way: override func keyboardWillShow(note: NSNotification) { super.keyboardWillShow(note) UIView.animateWithDuration(note.animationDuration) { // Your changes } }
-
Rafael Sachetto over 8 yearsDoesn't work in Swift 2 return the follow error: Value of type '[NSObject : AnyObject]?' has no member 'objectForKey'. The solution is (aNotification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSTimeInterval)
-
Lachtan over 8 years@RafaelSachetto try "valueForKey(..."
-
Dominic K almost 8 yearsFor Swift 2.2, I had to make two changes: for casting, you
as!
instead ofas
; and useUIViewAnimationOptions(rawValue: curve)
instead ofUIViewAnimations(curve)
. -
Shawn Baek almost 7 yearsHow to change the duration.?
-
Chris Conover over 6 yearsDid you query this from the existing animation?
-
Admin almost 5 yearsThe swift version works but should be: guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {return} print(duration) // you got animation's duration safely unwraped as a double let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as NSNumber //else do {return} print(curve)
-
PakitoV over 2 yearsto save 2 minutes to people like my future self: double duration = [[aNotification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; UIViewAnimationOptions curve = [[aNotification.userInfo objectForKey: UIKeyboardAnimationCurveUserInfoKey] integerValue];