我一直在做这样的事情来模仿旧版iOS上的键盘动画。
CGRect keyboardBeginFrame;
[[note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBeginFrame];
self.doneKeyboardButton.frame = CGRectMake(0, (keyboardBeginFrame.origin.y + keyboardBeginFrame.size.height) - 53, 106, 53);
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:self.doneKeyboardButton];
CGPoint newCenter = CGPointMake(self.doneKeyboardButton.superview.frame.origin.x + self.doneKeyboardButton.frame.size.width/2,
self.doneKeyboardButton.superview.frame.size.height - self.doneKeyboardButton.frame.size.height/2);
[UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]-.02
delay:.0
options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]
animations:^{
self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -TextFieldViewMovement);
self.doneKeyboardButton.center = newCenter;
}
completion:nil];
但是,这已停止在iOS7上运行。看起来返回的值不再完全正确,完成按钮不再完全模仿键盘显示动画。
答案 0 :(得分:84)
在iOS 7中,键盘使用新的未记录的动画曲线。虽然有些人注意到使用动态选项的未记录值有效,但我更喜欢使用以下内容:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
// work
[UIView commitAnimations];
虽然建议使用基于块的动画,但键盘通知返回的动画曲线为UIViewAnimationCurve
,而您需要传递给基于块的动画的选项为UIViewAnimationOptions
。使用传统的UIView动画方法,您可以直接输入值。最重要的是,这将使用新的未记录的动画曲线(整数值为7)并使动画与键盘匹配。并且,它在iOS 6和7上也能正常工作。
答案 1 :(得分:23)
我遇到了同样的问题,并设法让动画使用iOS 7的以下参数:
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:500.0f
initialSpringVelocity:0.0f
options:UIViewAnimationOptionCurveLinear
animations:animBlock
completion:completionBlock];
编辑:这些值是通过调试获得的, 可以 更改为新的iOS版本。 @DavidBeck's answer在iOS 7中也适用于我,所以我在这里链接它。
答案 2 :(得分:10)
Apple正在使用iOS 7中值为7的一些未记录的动画。
然而,UIViewAnimationCurve
的声明定义了0到3的值
typedef enum {
UIViewAnimationCurveEaseInOut, // 0
UIViewAnimationCurveEaseIn,
UIViewAnimationCurveEaseOut,
UIViewAnimationCurveLinear // 3
} UIViewAnimationCurve;
基于块的动画所需的UIViewAnimationOptions
定义为
enum {
// ...
UIViewAnimationOptionCurveEaseInOut = 0 << 16,
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
UIViewAnimationOptionTransitionNone = 0 << 20,
// ...
};
似乎Apple为动画曲线保留4位(20 - 16 = 4),允许从0到15的值(因此可能有更多未记录的值)。
有了这些知识,您只需将UIViewAnimationCurve
转换为UIViewAnimationOptions
即可将其转换为大约16位。在您的示例中,这意味着:
options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16
答案 3 :(得分:7)
您可以使用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];
快乐的编码!
<强>更新强>
您可以使用我编写的简单UIViewController类别https://github.com/Just-/UIViewController-KeyboardAnimation
答案 4 :(得分:0)
如果您想在工具栏中添加按钮(类似于移动版Safari所做的那样),您只需使用属性inputAccessoryView
(UITextField
和UITextView
都有)并为自己省去所有麻烦。这个隐藏的宝石鲜为人知,我很高兴我偶然发现它。
适用于iOS 6和iOS 7,我在我的应用Routie中使用它。
答案 5 :(得分:0)
这对我来说很合适......显示键盘时会捕获持续时间。我知道对这些选项进行硬编码意味着它可以在未来中断,但它适用于7和8.这对我们来说已经足够了......
[UIView animateWithDuration:self.animationDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self.view layoutIfNeeded]; completion:^(BOOL finished) {
if (finished)
{
if (completion)
completion();
}
}];
答案 6 :(得分:0)
iOS 10 +
雨燕5
更现代的替代方法(iOS 10+和Swift)是使用UIViewPropertyAnimator
,它不仅接受UIView.AnimationCurve
,而且是更现代的动画师。
您很有可能会使用UIResponder.keyboardAnimationCurveUserInfoKey
,我们将其视为NSNumber
。该密钥的文档是(Apple自己的符号,不是我的):
public class let keyboardAnimationCurveUserInfoKey: String // NSNumber of NSUInteger (UIViewAnimationCurve)
使用这种方法,我们可以消除任何猜测,只需即插即用:
if let kbDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber,
let kbTiming = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber, // doc says to treat as NSNumber
let timing = UIView.AnimationCurve.RawValue(exactly: kbTiming), // takes an NSNumber
let curve = UIView.AnimationCurve(rawValue: timing) // takes a raw value {
let duration = kbDuration.doubleValue
let animator = UIViewPropertyAnimator(duration: duration, curve: curve) {
// add animations
}
animator.startAnimation()
}