【问题标题】:Synchronizing Animations in keyboardWillShow keyboardWillHide -- Hardware Keyboard & Virtual Keyboard Simultaneously在 keyboardWillShow 中同步动画 keyboardWillHide -- 硬件键盘和虚拟键盘同时进行
【发布时间】:2014-04-11 05:27:14
【问题描述】:

序言

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

这是我正在使用的代码:

显示:

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

VirtualKeyboard w/ (UIViewAnimationOptions)animationCurve -- BROKEN

HardwareKeyboard w/ (animationCurve

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

问题:

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

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

【问题讨论】:

  • 你的问题很长,很难理解,伙计。尝试删除不必要的部分以增加可读性。
  • 你建议我剪什么?我想为人们提供所有必要的代码和解释来复制问题,并且我包含了视觉效果,以便人们可以看到我在说什么。我知道它很长,但我认为它最相关的信息。
  • 这里有同样的问题,如果您找到了解决方案,请在此处发布。
  • 您可以通过监听硬件键盘连接来解决它(取决于时间,我没有检查):stackoverflow.com/a/2893327/653513 - 并根据键盘类型使用适当的动画。虽然它是一个私有 API - 所以它可以作为概念验证。
  • @RicardoSánchez-Sáez - 我用的是 licecap,非常棒! cockos.com/licecap

标签: ios objective-c animation uiviewanimation uikeyboard


【解决方案1】:

由于苹果在键盘通知中给你发送的动画曲线没有对应的 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];

【讨论】:

  • 感谢 Adlai 的回答,我目前有几件事要做,但我会在今天晚些时候尝试一下,如果它解决了问题,请告诉您。
  • 嗨@Adlai,感谢您的回答。我无法让它工作。您是否对其进行了测试,还是只是一个想法?
  • 我已经对其进行了测试,它对我来说效果很好。你用的是什么动画代码?
  • 究竟是什么问题。我用你的代码替换了动画块。
  • 用你的textView.frame = …代码替换我的// Animation code评论
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多