Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the default iOS7 UIAnimation curve

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.

like image 421
Melvyn Hills Avatar asked Sep 18 '13 11:09

Melvyn Hills


2 Answers

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.

like image 109
Abizern Avatar answered Nov 10 '22 15:11

Abizern


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.

like image 45
Bob Spryn Avatar answered Nov 10 '22 13:11

Bob Spryn