在KeyboardWillShow中同步动画keyboardWillHide - 硬件键盘&虚拟键盘同时

时间:2014-03-07 21:09:40

标签: ios objective-c animation uiviewanimation uikeyboard

序言

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

以下是我使用的代码:

SHOW:

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

但有了这个,现在virtualKeyboard动画落后

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

示例

VirtualKeyboard w /(animationCurve&lt;&lt; 16) - 工作

VirtualKeyboard w/ (animationCurve << 16)

VirtualKeyboard w /(UIViewAnimationOptions)animationCurve - BROKEN

VirtualKeyboard w/ (UIViewAnimationOptions)animationCurve

HardwareKeyboard w /(animationCurve&lt;&lt; 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];

HANDLE TAP:

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

问题:

这里发生了什么,有没有一种方法可以获得一致的动画,无论虚拟/硬件键盘如何?

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

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:-1)

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