使用键盘将UIView向上动画移动

6

我有一个需求,需要在即将推出的项目中增加聊天功能。

与此同时,我一直在尝试实现我所期望的简单事情,即在屏幕底部添加一个UIView,其中包含一个UITextView。当用户点击UITextView时,它会随着键盘上移而动画效果显示。

我的实现方式已经能够正常工作,然而不幸的是,键盘的动画效果略慢于它上面的视图。以下是我的目前的实现方式:

注册键盘通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

键盘通知方法:

- (void)keyboardWillShow:(NSNotification*)notification
{
    CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
    NSInteger curve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];

    [UIView animateWithDuration:duration delay:0 options:curve animations:^{

        CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
        _chatViewBottomConstraint.constant = keyboardFrame.size.height;
        [self.view layoutIfNeeded];

    } completion:nil];
}

有没有其他人做过类似的事情,并能为我提供更好的解决方案?
2个回答

9
这对我有用:
- (void)keyboardWillShow:(id)keyboardDidShow
{
    [UIView beginAnimations:nil context:NULL];

    NSDictionary *userInfo = [keyboardDidShow userInfo];
    [UIView setAnimationDuration:[userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [self.view layoutIfNeeded];

    [UIView commitAnimations];
}

- (void)keyboardWillHide:(id)keyboardDidHide
{
    [UIView beginAnimations:nil context:NULL];

    NSDictionary *userInfo = [keyboardDidHide userInfo];
    [UIView setAnimationDuration:[userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];            
    [self.view layoutIfNeeded];

    [UIView commitAnimations];
}

更新: 或者您可以使用块相同的方式:

- (void)keyboardWillShow:(id)keyboardDidShow
{
    NSDictionary *userInfo = [keyboardDidShow userInfo];
    [UIView animateWithDuration:[userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]
                          delay:0.f
                        options:[[keyboardDidShow userInfo][UIKeyboardAnimationCurveUserInfoKey] intValue] << 16
                     animations:^{
        ...
    } completion:^(BOOL finished) {
        ...
    }];
}

- (void)keyboardWillHide:(id)keyboardDidHide
{
    NSDictionary *userInfo = [keyboardDidHide userInfo];
    [UIView animateWithDuration:[userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]
                          delay:0.f
                        options:[[keyboardDidHide userInfo][UIKeyboardAnimationCurveUserInfoKey] intValue] << 16
                     animations:^{
        ...
    } completion:^(BOOL finished) {
        ...
    }];
}

你为什么要使用已弃用的动画方法而不是基于块的语法? - Jesse Rusak
好的,我明白了。把它放在一个块中会减少错误的发生。;) - electronix384128
1
使用块方法似乎导致键盘和视图到达目的地之间出现延迟问题。如果使用动画方法,它可以正常工作。有什么想法吗?在动画块内部,我有: _chatViewBottomConstraint.constant = keyboardFrame.size.height; [self.view layoutIfNeeded]; - Nick
1
Ben的代码中有一个bug;曲线不能直接传递给选项。请参见:https://dev59.com/aGw05IYBdhLWcg3wSABH - Jesse Rusak
非常感谢大家,你们帮了我很多。 - Nick
显示剩余3条评论

5

通知 userInfo 字典中包含动画持续时间 (UIKeyboardAnimationDurationUserInfoKey) 和曲线 (UIKeyboardAnimationCurveUserInfoKey) 信息;如果您同时使用 两者,则您的动画应与键盘动画时间相匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接