如何在iOS 7上模拟键盘动画以添加;“完成”;按钮到数字键盘?
我一直在做类似的事情来模仿旧版iOS上的键盘动画如何在iOS 7上模拟键盘动画以添加;“完成”;按钮到数字键盘?,ios,objective-c,animation,uiview,keyboard,Ios,Objective C,Animation,Uiview,Keyboard,我一直在做类似的事情来模仿旧版iOS上的键盘动画 CGRect keyboardBeginFrame; [[note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBeginFrame]; self.doneKeyboardButton.frame = CGRectMake(0, (keyboardBeginFrame.origin.y + keyboardBeginFrame.size.
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上已经停止工作。似乎返回的值不再完全正确,并且“完成”按钮不再完全模仿键盘显示动画。我也遇到了同样的问题,并设法使动画与iOS 7的以下参数一起工作:
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:500.0f
initialSpringVelocity:0.0f
options:UIViewAnimationOptionCurveLinear
animations:animBlock
completion:completionBlock];
编辑:这些值是通过调试获得的,可以使用新的iOS版本进行更改。在iOS 7中也适用于我,因此我将其链接到这里。在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和iOS 7上也同样有效。如果你想在工具栏中添加按钮(类似于移动Safari),你可以使用属性inputAccessoryView
(既UITextField
又UITextView
都有),省去所有麻烦。这个隐藏的宝石鲜为人知,我很高兴我偶然发现了它
它可以在iOS 6和iOS 7上运行,我正在我的应用程序中使用它。苹果正在使用一些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,
// ...
};
您可以使用
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类别这对我来说很好。。。显示键盘时会捕获持续时间。我知道对选项进行硬编码意味着它将来可能会崩溃,但它适用于7和8。这对我们来说已经足够好了
[UIView animateWithDuration:self.animationDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self.view layoutIfNeeded]; completion:^(BOOL finished) {
if (finished)
{
if (completion)
completion();
}
}];
iOS 10+
Swift 5 一个更现代的选择(iOS 10+和Swift)是使用
UIViewPropertyAnimator
,它不仅接受UIView.AnimationCurve
,而且是一个更现代的动画师
您很可能正在使用UIResponder.keyboardanimationcurveUserInfo
,我们将其视为NSNumber
。此密钥的文档是(苹果自己的符号,不是我的):
使用这种方法,我们可以消除任何猜测,只需即插即用:
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()
}
我认为你是正确的,因为我原来的解决方案不是很稳定。更好,因为它简单、理论上完美且稳定(向后和向前兼容),而此答案中使用的参数可能不准确,即使它们非常适合iOS 7.0(as),也可能不适合其他版本的iOS。例如,我很确定他们已经停止使用iOS<7.0。完美,帮我这么多+1简单!强健的天才!这个解决方案还让我摆脱了我的
aacviewanimationoptions fromCurve
函数。只是用这个旧样式替换了我所有的键盘动画块。感觉像是退后了一步,但效果不错。我期待着在苹果意识到它的错误后回到区块。我读到,你可以简单地将曲线值移动16,得到期权值options=curve@Brennan使用UIViewAnimationCurve curve=[[info objectForKey:UIKeyboardAnimationCurveUserInfo]integerValue]
获取曲线,并像这样使用块动画UIView animateWithDuration:duration delay:delay选项:(将其转换为Swift的曲线很简单,除了需要这一点的曲线参数:var curve:UIViewAnimationCurve=UIViewAnimationCurve(rawValue:info[UIKeyboardAnimationCurveUserInfo]!.integerValue)!
。这是个不错的主意,但这个问题更多地集中在如何在数字键盘中未使用的按钮空间中添加叠加按钮。啊,好的。我想这意味着按钮将位于键盘上方。它应该添加到哪里?左下角?我不知道,这似乎很不寻常。但也许我可以帮上忙,因为我将自己创建整个键盘(我需要.和-那里),并将其放在GitHub上。我相信你指的是4位。:)这种方法仍然将枚举值硬编码到程序逻辑中。从我的角度来看,这不太好,非常不面向对象。实际上,在思考了大约-3秒后,我同意了安东的答案。我尝试了这种方法,当你选择答案时。但我不知道你是如何设置框架的。特别是self.contentview.frame。
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()
}