如何使用默认的iOS7 UIAnimation曲线

19

iOS7的动画效果与iOS6不同,它们似乎使用了不同的贝塞尔曲线。iOS6使用的是一种“easeInOutSine”曲线,而iOS7更像是“easeInOutExpo”曲线。(http://matthewlein.com/ceaser/

有没有办法使用这个曲线?我想在键盘打开或关闭时同步我的动画。

2个回答

39

这是我的做法(至少当键盘即将显示时)

- (void)keyboardWillShow:(NSNotification *)notification {
    NSDictionary *keyboardAnimationDetail = [notification userInfo];
    UIViewAnimationCurve animationCurve = [keyboardAnimationDetail[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    CGFloat duration = [keyboardAnimationDetail[UIKeyboardAnimationDurationUserInfoKey] floatValue];

    [UIView animateWithDuration:duration delay:0.0 options:(animationCurve << 16) animations:^{
        // Set the new properties to be animated here
    } completion:nil];
}

像往常一样,您可以从键盘通知中获取动画曲线,并通过位移将其转换为动画选项。


1
这真的很聪明。在键盘显示之前,如何实现该动画呢? - samvermette
3
只需将(7 << 16)用作animateWithDuration的选项。 - note173
有没有官方常量来表示那个选项? - Melvyn Hills
它们在头文件中。我认为它有点脆弱,因为它取决于实现。真的应该有一个框架方法将animationCurve转换为animationOption。我应该随时为此提出雷达反馈。 - Abizern
1
当键盘出现时,这很完美,但为什么当键盘被解除时它不同步? - Piotr Tomasik
显示剩余5条评论

3

更新,已在7.1版本中修复,不再需要此操作。


出于某种原因,在键盘消失时报告的动画曲线是不正确的。实际上,它似乎是6 << 16而不是7 << 17。

下面是我使用UIKeyboardWillChangeFrameNotification来确定要使用哪个动画曲线的方法。

NSDictionary *keyboardAnimationDetail = [notification userInfo];

CGRect keyboardEndFrameWindow = [keyboardAnimationDetail[UIKeyboardFrameEndUserInfoKey] CGRectValue];

double keyboardTransitionDuration  = [keyboardAnimationDetail[UIKeyboardAnimationDurationUserInfoKey] doubleValue];

// gives incorrect value of 7 on dismissal
// UIViewAnimationCurve keyboardTransitionAnimationCurve  = [keyboardAnimationDetail[UIKeyboardAnimationCurveUserInfoKey] integerValue];

CGRect keyboardEndFrameView = [self.view convertRect:keyboardEndFrameWindow fromView:nil];

CGFloat newConstant = (self.view.frame.size.height - keyboardEndFrameView.origin.y);

[UIView animateWithDuration:keyboardTransitionDuration
                      delay:0.0f
                    options:newConstant == 0 ? (6 << 16) : (7 << 16)
                 animations:^{
                     self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, 0, self.view.frame.size.height - keyboardEndFrameView.origin.y + self.commentToolbar.frame.size.height, 0);
                     self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(self.tableView.scrollIndicatorInsets.top, 0, self.view.frame.size.height - keyboardEndFrameView.origin.y + self.commentToolbar.frame.size.height, 0);
                     self.commentViewToSuperviewBottomConstraint.constant = (self.view.frame.size.height - keyboardEndFrameView.origin.y);
                     [self.view layoutIfNeeded];
                 }
                 completion:^(__unused BOOL finished){
                 }];

基本上,我确定键盘框架是否隐藏,方法是查看新的y坐标是否将刚好超出我们视图的框架(newConstant)。然后根据这个来使用6或7:

newConstant == 0 ? (6 << 16) : (7 << 16)

其余的只是调整我的tableViewcontentInsetscrollIndicatorInsets,以及更改随着键盘移动的工具栏上的常量。


@Abizem的语法确实看起来更漂亮。 - Bob Spryn
2
似乎在7.0.3中已经修复。 - runmad
我认为它在7.0.3中没有被修复,但是在7.1中已经修复了。 - Bob Spryn

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