objective-c iOS 7 - 键盘动画
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18957476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS 7 - Keyboard animation
提问by Paul Warkentin
I'm trying to understand the new keyboard animation in iOS 7.0 on the iPhone 5 Simulator. I want to resize my UITableViewwhen the keyboard appears, but I can't get the right animation details.
I'm using the information from the NSNotificationobject, when the keyboard appears or disappears.
我正在尝试了解 iPhone 5 模拟器上 iOS 7.0 中的新键盘动画。我想UITableView在键盘出现时调整我的大小,但我无法获得正确的动画细节。当键盘出现或消失时,
我正在使用来自NSNotification对象的信息。
Here is my log:
这是我的日志:
Move keyboard from {{0, 920}, {320, 216}} to {{0, 352}, {320, 216}}
with duration: 0.400000
and animation curve: 7
UIViewAnimationCurveEaseInOut = 0
UIViewAnimationCurveEaseIn = 1
UIViewAnimationCurveEaseOut = 2
UIViewAnimationCurveLinear = 3
The animation curve is an unknown value, what should I do?
动画曲线是未知值,怎么办?
采纳答案by Paul Warkentin
Now I found the solution. The animation starts from the point {0, 920}to {0, 352}. The problem was that the UITableViewobject started with a size of {160, 568}, so I changed the size of the UITableViewto {160, 920}before the animation was started.
现在我找到了解决方案。动画从点{0, 920}到开始{0, 352}。问题是,该UITableView物体开始与大小的{160, 568},所以我改变的大小UITableView,以{160, 920}动画开始前。
Concerning to the unknown animation curve, I just set the parameter to animationCurve << 16to convert it from a view animation curve to a view animation option.
The value is not equal to the linear, ease in, ease out and ease inout animation curve.
对于未知的动画曲线,我只是将参数设置animationCurve << 16为将其从视图动画曲线转换为视图动画选项。
该值不等于linear、ease in、ease out和ease inout动画曲线。
Here is my code:
这是我的代码:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
and:
和:
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
//
// Get keyboard size.
NSValue *beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardBeginFrame = [self.view convertRect:beginFrameValue.CGRectValue fromView:nil];
NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];
//
// Get keyboard animation.
NSNumber *durationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration = durationValue.doubleValue;
NSNumber *curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey];
UIViewAnimationCurve animationCurve = curveValue.intValue;
//
// Create animation.
CGRect tableViewFrame = self.tableView.frame;
bTableViewFrame.size.height = (keyboardBeginFrame.origin.y - tableViewFrame.origin.y);
self.tableView.frame = tableViewFrame;
void (^animations)() = ^() {
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = (keyboardEndFrame.origin.y - tableViewFrame.origin.y);
self.tableView.frame = tableViewFrame;
};
//
// Begin animation.
[UIView animateWithDuration:animationDuration
delay:0.0
options:(animationCurve << 16)
animations:animations
completion:nil];
}
回答by David Beck
In iOS 7, the keyboard uses a new, undocumented animation curve. While some have noted that using an undocumented value for the animation option, I prefer to use the following:
在 iOS 7 中,键盘使用了一种新的、未记录的动画曲线。虽然有些人注意到对动画选项使用未记录的值,但我更喜欢使用以下内容:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
// work
[UIView commitAnimations];
While block based animations are the recommendation, the animation curve returned from the keyboard notification is an UIViewAnimationCurve, while the option you would need to pass to block based animations is an UIViewAnimationOptions. Using the traditional UIView animation methods allows you to pipe the value directly in. Most importantly, this will use the new undocumented animation curve (integer value of 7) and cause the animation to match the keyboard. And, it will work just as well on iOS 6 and 7.
虽然推荐使用基于块的动画,但从键盘通知返回的动画曲线是UIViewAnimationCurve,而您需要传递给基于块的动画的选项是UIViewAnimationOptions。使用传统的 UIView 动画方法允许您直接输入值。最重要的是,这将使用新的未记录动画曲线(整数值为 7)并使动画与键盘匹配。而且,它在 iOS 6 和 7 上也能正常工作。
回答by Anton Gaenko
You can use animateWithDurationblock and set curve inside it. It's clean and work well.
您可以使用animateWithDuration块并在其中设置曲线。它很干净而且运行良好。
UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
double duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[UIView setAnimationCurve:curve];
/* ANIMATION HERE */
// don't forget layoutIfNeeded if you use autolayout
}
completion:nil];
Happy coding!
快乐编码!
UPDATE
更新
You can use a simple UIViewController category written by me https://github.com/Just-/UIViewController-KeyboardAnimation
你可以使用我写的一个简单的 UIViewController 类别https://github.com/Just-/UIViewController-KeyboardAnimation
回答by Jeffrey Sun
Use UIKeyboardWillChangeFrameNotificationinstead, because some international keyboards, like the Chinese keyboard, change height during use. Also this code gives you the correct heights for the keyboard, even in landscape mode. (Note: the code below is for Autolayout)
使用UIKeyboardWillChangeFrameNotification替代,因为一些国际化的键盘,就像 CN 的键盘,在使用过程中改变高度。此外,此代码为您提供正确的键盘高度,即使在横向模式下也是如此。(注意:下面的代码用于自动布局)
//set your observer, in a method like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void)keyboardWillChange:(NSNotification *)notification {
CGRect initialRect = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat initialHeight = self.view.frame.size.height - [self.view convertRect:initialRect fromView:nil].origin.y;
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat newHeight = self.view.frame.size.height - [self.view convertRect:keyboardRect fromView:nil].origin.y;
//set your constraints here, based on initialHeight and newHeight, which are the heights of the keyboard before & after animation.
[self.contentView setNeedsUpdateConstraints];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.contentView layoutIfNeeded];
[UIView commitAnimations];
}
回答by invoodoo
To use the same animation as keyboard has, you have to use undocumented Curve option.
要使用与键盘相同的动画,您必须使用未记录的曲线选项。
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
CGRect rect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
NSInteger curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16;
[UIView animateWithDuration:animationDuration delay:0.0 options:curve animations:^{
} completion:nil];
}
I found that actually method animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:is the new way that all animations are done in iOS7 and iOS8 now. You just make right duration, damping and velocity and you will get the same effect, but even you can change speed/time.
我发现实际上方法animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:是现在在 iOS7 和 iOS8 中完成所有动画的新方法。您只需设置正确的持续时间、阻尼和速度,您将获得相同的效果,但即使您也可以更改速度/时间。
回答by Anu Mittal
In Swift 4?
在 Swift 4 中?
Add observers for keyboard notifications:?
为键盘通知添加观察者:?
- UIKeyboardDidShowNotification
- UIKeyboardDidHideNotification
- UIKeyboardDidShowNotification
- UIKeyboardDidHideNotification
via
通过
NSNotificationCenter.defaultCenter().addObserver(_ observer: Any,
selector aSelector: Selector,
name aName: NSNotification.Name?,
object anObject: Any?)
And implement selector to animate the UI with Keyboard animation. In order to create a valid curve value we need to shift UIResponder.keyboardAnimationCurveUserInfoKey by << 16?
并实现选择器以使用键盘动画为 UI 设置动画。为了创建一个有效的曲线值,我们需要将 UIResponder.keyboardAnimationCurveUserInfoKey 移动 << 16?
func keyboardWillShow(_ notification: Notification!) {
if let info = notification.userInfo {
let keyboardSize = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double
let curveVal = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.intValue ?? 7 // default value for keyboard animation
let options = UIView.AnimationOptions(rawValue: UInt(curveVal << 16))
UIView.animate(withDuration: duration, delay: 0, options: options, animations: {
// any operation to be performed
}, completion: nil)
}
}
回答by Rivera
In iOS 13 you are in an implicit animation, so just modify your layout inside your notification handler and it will animate with the correct duration and curve.
在 iOS 13 中,您处于隐式动画中,因此只需在通知处理程序中修改布局,它就会以正确的持续时间和曲线进行动画处理。
回答by Michael Peterson
Register for the notification:
注册通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Respond by animating a change to the frame.origin.y of the view.
通过动画更改视图的 frame.origin.y 来响应。
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[aNotification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
CGRect searchButtonFrame = self.searchButton.frame;
searchButtonFrame.origin.y = (keyboardEndFrame.origin.y - searchButtonFrame.size.height);
self.searchButton.frame = searchButtonFrame;
[UIView commitAnimations];
}

