1

I'm trying to move a box from point A = (0, 0) to B = (0, 1000) but I want to slow down as it approaches point B. I tried UIViewAnimationOptionCurveEaseOut but it seems to be moving at a constant velocity.

UIView *box = [[UIView alloc] init];
box.frame = CGRectMake(0, 0, 500, 500);
box.backgroundColor = [UIColor redColor];
[self.view addSubview:box];

// Animation
[UIView animateWithDuration:0.3
                  delay:0.0
                options:UIViewAnimationOptionCurveEaseOut
             animations:^{

                 box.frame = CGRectMake(0, 1000, box.frame.size.width, box.frame.size.height);
             } completion:nil];

Any ideas?

Vulkan
  • 1,004
  • 16
  • 44
  • Have you tried to set the animation duration to 2 or 3 seconds? Maybe it's not that easy to see if the animation slows down in 0.3 seconds... – Mischa Jul 25 '14 at 13:00
  • Animations in the frame of UI interactions are always set below 0.5 seconds. Otherwise, it's too slow. Imagine waiting 3 seconds every time you want to do something. The box, is an example, I don't really want to move a box, but a UIWebView. I want to duplicate the bounce effect of the UIScrollView in the UIWebView. Go to the top of the page and flick it downwards, it moves back to top but as it approaches top it slows down significantly. – Vulkan Jul 25 '14 at 13:08
  • I understand that. My idea was just for testing and making sure the animation doesn't slow down. – Mischa Jul 25 '14 at 13:13

3 Answers3

2

The easiest solution is to do the animation in multiple stages, with different speed, e.g. like this:

// Animation stage 1
[UIView animateWithDuration:0.1 //First half is fast
                      delay:0.0
                    options:UIViewAnimationOptionCurveEaseIn
                 animations:^{

                     box.frame = CGRectMake(0, 500, box.frame.size.width, box.frame.size.height);
                 } completion:^(BOOL finished) {

                     // Animation stage 2
                     [UIView animateWithDuration:0.2 //Second half slower
                                           delay:0.0
                                         options:UIViewAnimationOptionCurveEaseOut
                                      animations:^{

                                          box.frame = CGRectMake(0, 1000, box.frame.size.width, box.frame.size.height);
                                      } completion:nil];

                 }];

It should be possible to get a smooth animation by playing around with it a bit.

1

If this is iOS 7+, use spring animations. Add this code to viewDidAppear: to test it out and see the difference between using a spring vs. a simple ease out curve.

Also note that Apple really encourages the use of spring animations going forward, since almost all (or all?) of their animations in iOS 7+ are done with springs.

UIView *fooView = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 50, 50)];
fooView.backgroundColor = [UIColor redColor];
[self.view addSubview:fooView];

[UIView animateWithDuration:1
                      delay:1
     usingSpringWithDamping:1
      initialSpringVelocity:1
                    options:0
                 animations:^{
                     fooView.frame = CGRectMake(50, 400, 50, 50);
                 }
                 completion:nil];

UIView *barView = [[UIView alloc] initWithFrame:CGRectMake(200, 100, 50, 50)];
barView.backgroundColor = [UIColor redColor];
[self.view addSubview:barView];

[UIView animateWithDuration:1
                      delay:1
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     barView.frame = CGRectMake(200, 400, 50, 50);
                 }
                 completion:nil];
colinbrash
  • 481
  • 2
  • 11
0

If you're not satisfied with built-in easing functions you can create your own. You want something related to CAMediaTimerFunction or CAKeyframeAnimation. You can read about it here and here. There's also some good answers here.

Community
  • 1
  • 1
MANIAK_dobrii
  • 6,014
  • 3
  • 28
  • 55