在键盘上同步animation键盘将同时显示键盘和硬件键盘和虚拟键盘

前言

所以我有一个以聊天部分为特色的应用程序,我正在同步键盘隐藏和显示的animation以及聊天input的兴衰。

以下是我正在使用的代码:

显示:

- (void) keyboardWillShow:(NSNotification *)note { NSDictionary *keyboardAnimationDetail = [note userInfo]; UIViewAnimationCurve animationCurve = [keyboardAnimationDetail[UIKeyboardAnimationCurveUserInfoKey] integerValue]; CGFloat duration = [keyboardAnimationDetail[UIKeyboardAnimationDurationUserInfoKey] floatValue]; NSValue* keyboardFrameBegin = [keyboardAnimationDetail valueForKey:UIKeyboardFrameBeginUserInfoKey]; CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue]; // working for hardware keyboard //UIViewAnimationOptions options = (UIViewAnimationOptions)animationCurve; // working for virtual keyboard UIViewAnimationOptions options = (animationCurve << 16); [UIView animateWithDuration:duration delay:0.0 options:options animations:^{ textView.frame = CGRectMake(0, self.view.bounds.size.height - keyboardFrameBeginRect.size.height, self.view.bounds.size.width, -40); } completion:nil]; } 

隐藏:

 - (void) keyboardWillHide:(NSNotification *)note { NSDictionary *keyboardAnimationDetail = [note userInfo]; UIViewAnimationCurve animationCurve = [keyboardAnimationDetail[UIKeyboardAnimationCurveUserInfoKey] integerValue]; CGFloat duration = [keyboardAnimationDetail[UIKeyboardAnimationDurationUserInfoKey] floatValue]; // hardware keyboard //UIViewAnimationOptions options = (UIViewAnimationOptions)animationCurve; // virtual keyboard UIViewAnimationOptions options = (animationCurve << 16); [UIView animateWithDuration:duration delay:0.0 options:options animations:^{ textView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, -40); } completion:nil]; } 

这对于虚拟键盘来说效果很好,但是如果keyboardWillShow:或keyboardWillHide:由于断开或连接硬件键盘而被调用,则animation会滞后。 我可以通过更改UIViewAnimationOptions来解决这个问题

更换:

 // Works with virtual keyboard UIViewAnimationOptions options = (animationCurve << 16); 

附:

 // working for firstResponder keyboard UIViewAnimationOptions options = (UIViewAnimationOptions)animationCurve; 

但是有了这个,现在virtualKeyboardanimation就落后了

我意识到,硬件键盘animation不是很常见,也许不是最重要的问题,但我喜欢一切工作!

例子

VirtualKeyboard w /(animationCurve << 16) – WORKING

VirtualKeyboard w /(animationCurve << 16)

VirtualKeyboard W /(UIViewAnimationOptions)animationCurve – BROKEN

VirtualKeyboard瓦特/(UIViewAnimationOptions)animationCurve

HardwareKeyboard w /(animationCurve << 16) – BROKEN

HardwareKeyboard w /(animationCurve << 16)

HardwareKeyboard w /(UIViewAnimationOptions)animationCurve – WORKING

HardwareKeyboard w /(UIViewAnimationOptions)animationCurve

笔记

在模拟器cmd + shft + k中模拟硬件键盘

是的,这是可以在真实设备上复制的。

如果你想要的话,这里是我的代码的其余部分,只是为了复制的目的

添加文本视图

 textView = [UITextView new]; textView.layer.borderWidth = 10; textView.layer.borderColor = [UIColor blackColor].CGColor; textView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, -40); [self.view addSubview:textView]; UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]init]; [tap addTarget:self action:@selector(handleTap:)]; [self.view addGestureRecognizer:tap]; // OBSERVE KEYBOARD [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 

手柄敲击:

 - (void) handleTap:(UITapGestureRecognizer *)tap { NSLog(@"tapped"); [textView resignFirstResponder]; } 

问题:

这里发生了什么事情,是否有一个好方法来获得一致的animation,无论虚拟/硬件键盘?

我意识到这是漫长的,谢谢你的阅读!

由于Apple在键盘通知中发送的animation曲线没有相应的UIViewAnimationOption位,因此您需要将其拖放到老派的非块animation并直接使用曲线:

 NSTimeInterval duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; UIViewAnimationCurve curve = [note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; [UIView beginAnimations:@"SomeAnimationID" context:NULL]; [UIView setAnimationCurve:curve]; [UIView setAnimationDuration:duration]; // Animation code [UIView commitAnimations]; 

keyboardWillShow:

 NSDictionary *info = [notification userInfo]; CGRect keyboardFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue]; NSTimeInterval duration = [info[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; UIViewAnimationCurve curve = [info[UIKeyboardAnimationCurveUserInfoKey] integerValue]; [self layoutIfNeeded]; [UIView animateWithDuration:duration delay:0 options:(curve << 20) animations:^{ [self.keyboardConstraint setConstant:keyboardFrame.size.height]; [self layoutIfNeeded]; } completion:nil];