How to use the default iOS7 UIAnimation curve
Asked Answered
P

2

19

iOS7 animations don't behave the same way as in iOS6. They appear to use a different bezier curve. Where iOS6 uses a kind of "easeInOutSine" curve, iOS7 is more of the "easeInOutExpo" kind. (http://matthewlein.com/ceaser/)

Is there a way to use that curve? I want to sync my animations when the keyboard opens/closes.

Phocomelia answered 18/9, 2013 at 11:0 Comment(0)
J
39

Here's how I do it (at least when the keyboard is about to be shown)

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

You get the animation curve from the keyboard notification as usual and translate it to an animation option by bit-shifting it.

Jedthus answered 18/9, 2013 at 13:40 Comment(9)
This is really clever. How would one get that animation before the keyboard is ever shown?Ender
Just use (7 << 16) as an option for animateWithDuration.Elviraelvis
Is there an official constant for that option?Phocomelia
They are in the headers. I think it's a bit fragile myself as it depends on the implementation. There really should be a framework method to convert an animationCurve to an animationOption. I should raise a radar for it sometime.Jedthus
Any thoughts on how to use this animation curve for a CAAnimation?Ender
This is perfect for when the keyboard shows up, but why is it out of sync when the keyboard is dismissed?Normative
Yeah this seems to be off for the keyboard dismissal.Caterwaul
Interesting. The dismissing animation seems to be (6 << 16) even though it's reported to be (7 << 16)Caterwaul
However, the duration parameter is invalid when using this animation option. Can anyone solve this?Six
C
3

Update, fixed in 7.1. No longer necessary.


For whatever reason, the animation curve reported on keyboard dismissal is incorrect. It seems to actually be 6 << 16 instead of 7 << 17.

Here's what I do with UIKeyboardWillChangeFrameNotification to determine which animation curve to use.

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

Basically I determine if the keyboard frame is hiding by seeing if the new y origin will be just outside our view's frame (newConstant). Then based on that I use either 6 or 7:

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

The rest is just adjusting my tableView contentInset and scrollIndicatorInsets, as well as changing the constant on the toolbar that is moving with the keyboard.

Caterwaul answered 17/10, 2013 at 23:54 Comment(3)
@Abizem's syntax certainly looks much nicer.Caterwaul
Seems to be fixed in 7.0.3Outman
I don't think it was fixed in 7.0.3, but it IS fixed in 7.1.Caterwaul

© 2022 - 2024 — McMap. All rights reserved.