ios - 在 keyboardWillShow keyboardWillHide 中同步动画——同时使用硬件键盘和虚拟键盘

标签 ios objective-c animation uiviewanimation uikeyboard

序言

所以我有一个以聊天部分为特色的应用程序,我正在同步键盘隐藏和显示的动画与聊天输入的上升和下降。

这是我使用的代码:

显示:

- (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:,则动画会滞后。我可以通过更改 UIViewAnimationOptions 来解决这个问题

替换:

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

与:

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

但是有了这个,现在虚拟键盘动画滞后了

我意识到硬件键盘动画不是很常见,这可能不是最重要的问题,但我喜欢一切正常工作!

例子

虚拟键盘 w/(animationCurve << 16) -- 工作

VirtualKeyboard w/ (animationCurve << 16)

带 (UIViewAnimationOptions)animationCurve 的虚拟键盘 -- 损坏

VirtualKeyboard w/ (UIViewAnimationOptions)animationCurve

HardwareKeyboard w/(animationCurve << 16) -- 坏了

HardwareKeyboard w/ (animationCurve << 16)

带 (UIViewAnimationOptions)animationCurve 的硬件键盘 -- 工作

HardwareKeyboard w/ (UIViewAnimationOptions)animationCurve

注释

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

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

如果您需要,这是我的其余代码,仅用于复制目的

添加 TextView

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];
}

问题:

这是怎么回事,是否有一种无论虚拟/硬件键盘如何都能获得一致动画的好方法?

我知道这很长,感谢您的阅读!

最佳答案

由于 Apple 在键盘通知中发送给您的动画曲线没有相应的 UIViewAnimationOption 位,因此您需要下拉到老式非 block 动画并直接使用曲线:

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];

关于ios - 在 keyboardWillShow keyboardWillHide 中同步动画——同时使用硬件键盘和虚拟键盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22260711/

相关文章:

iphone - 根据预处理器宏值更改基本 url

ios - AFNetworing - setImageWithURLRequest 不工作

javascript - HTML5 Canvas 基本线条动画

ios - 新的 view.frame.y 与 label.frame.y 不匹配

ios - ios开发中的WSDL webservice

ios - 从字符串到字符串的条件转换总是在 swift 3 中成功

objective-c - CoreLocation 对象,无法分配经度

jquery - 滑动从右向左切换

javascript - 为什么动画 d3 svg 线在 IE9 中不与轴偏移同步,但在 IE11 和 Chrome 中同步?

android - 在 Flutter 的垂直列表中添加动态高度水平 ListView