1

I have this animation with one background image and 12 images of the needle in the center. its running ok, but each time it shows image and the image after, I just want it to run smooth between the images. how can I do that?

here is my current code:

- (IBAction)startAnimation:(id)sender
{
    imgAnimation.frame = CGRectMake(0, 0, 184.5f, 172.5f);
    imgAnimation.center = CGPointMake(160, 164);
    imgAnimation.animationImages = [NSArray arrayWithObjects:
                                [UIImage imageNamed:@"pointer01.png"],
                                [UIImage imageNamed:@"pointer02.png"],
                                [UIImage imageNamed:@"pointer03.png"],
                                [UIImage imageNamed:@"pointer04.png"],
                                [UIImage imageNamed:@"pointer05.png"],
                                [UIImage imageNamed:@"pointer06.png"],
                                [UIImage imageNamed:@"pointer07.png"],
                                [UIImage imageNamed:@"pointer08.png"],
                                [UIImage imageNamed:@"pointer09.png"],
                                [UIImage imageNamed:@"pointer10.png"],
                                [UIImage imageNamed:@"pointer11.png"],
                                [UIImage imageNamed:@"pointer12.png"], nil];
    [imgAnimation setAnimationRepeatCount:5];
    [imgAnimation setAnimationDuration:4.0f];
    [imgAnimation startAnimating];

}

gauge gauge

ytpm
  • 4,962
  • 6
  • 56
  • 113

1 Answers1

3

Edit: I originally suggested UIView animation, but that always takes the shortest possible route, rotating through 90 degrees instead of 270. Try this, courtesy of Can I use CGAffineTransformMakeRotation to rotate a view more than 360 degrees?

To get the smoothest possible needle animation, don't use a sequence of images. Start with a single needle image, in a UIImageView, with the view centered on the background dial image. Then change the transform property of the UIImageView's layer with an transform for rotation.

Once you have the geometry lined up, use Core Animation to animate the transform changing through the appropriate range of angles.

Just to elaborate, assuming that imgAnimation is a UIImageView:

- (IBAction)startAnimation:(id)sender
{
    // This assumes that the center of the needle image is the center of the dial.  If they aren't, it's probably simplest to resize the needle image so it is centered.
    imgAnimation.frame = CGRectMake(0, 0, 184.5f, 172.5f);
    imgAnimation.center = CGPointMake(160, 164);

    // The needle image used should show the needle pointing straight up, or some other known direction.
    imgAnimation.image = [UIImage imageNamed:@"pointer06.png"];
    // Position the needle in its position before animating.
    [imgAnimation.layer setTransform:CATransform3DMakeRotation(-M_PI*3/4, 0, 0, 1)];

    // Construct an animation moving the needle to its end position.
    // Mose of these properties should be self-explanatory.  Look up the CABasicAnimation Class Reference if not.
    CABasicAnimation *needleAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    needleAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    needleAnim.duration = 4;
    needleAnim.repeatCount = 5;
    needleAnim.autoreverses = YES;
    // Setting fillMode means that, once the animation finishes, the needle stays in its end position.
    needleAnim.fillMode = kCAFillModeForwards;
    needleAnim.removedOnCompletion = YES;
    needleAnim.toValue = [NSNumber numberWithFloat:M_PI*3/4];

    // Add the animation to the needle's layer.
    [senderView.layer addAnimation:needleAnim forKey:nil];
}
Community
  • 1
  • 1
Cowirrie
  • 7,218
  • 1
  • 29
  • 42
  • I've added source code to the explanation. You will need to make some adjustments to get the angles right. – Cowirrie Apr 07 '12 at 21:33
  • wow man, thanks alot! you have no idea how it helped me! thanks! – ytpm Apr 10 '12 at 21:27
  • Dondragmer, hey man. thanks again. I've changed the first CGAffineTransformMakeRotation to (0) and the second one, I leave the same. now it starts on the left to the right, but stopes on the middle. how can I make him go all the way? when I change something he is going from left to right, but from the bottom - it's wrong. Thanks again. – ytpm Apr 11 '12 at 15:19
  • @Yossi Tsafar: Which pointer image are you using? I recommended using an image with the point pointing straight up. If you do that, the needle will need to start rotated 135 degrees (pi*3/4 radians) to the left, and finish rotated the same amount to the right. If you use a different image, you will need to change both the starting and ending angles. – Cowirrie Apr 11 '12 at 22:49
  • I'm using the image with the needle pointing to the zero. and I want it to start from zero to 100 and stop there. but its only going 3.14 (PI) I dont know why and stops always on 65. when I change the second CGAffineTransformMakeRotation to something more than 3.14 it always goes from the bottom. how can I fix that? – ytpm Apr 12 '12 at 04:22
  • I see. That problem is discussed over at [Basic keyframe animation (rotation)](http://stackoverflow.com/q/1031177/1318452), although they're animating the CALayer instead of using blocks as I did here. – Cowirrie Apr 12 '12 at 04:29
  • See my edited solution. Instead of rotating the view, rotate its layer using a `CATransform3D`. You'll still need to fix up the angles, but it should now rotate as many times as you like. – Cowirrie Apr 12 '12 at 04:56
  • OK man, it works great! thanks allot! but the only problem is that when the needle reach the end, it comes back to the start value. how could I cancel that? – ytpm Apr 12 '12 at 11:21
  • See `duration`, `repeatCount` and `autoreverses`? Think about them. – Cowirrie Apr 12 '12 at 11:37
  • Also, you'll need to set `fillMode`. I've edited my answer to apply this. Thanks to [Why CAAnimation Rotation is returning to previous state](http://stackoverflow.com/q/2832758/1318452). – Cowirrie Apr 12 '12 at 23:15