开发者

Why do I need to do this and is there a better way? Animation blocks on iPhone app OS4

So I have some animation blocks to create some very simple animations on my app (eg. a wheel spinning continuously). This is the code for the animation (I have changed if from the old commitanimations style block but was getting the same problem with that).

[UIView animateWithDuration:30 delay:0.0
     options:(UIViewAnimationOptionAllowUserInteraction |
     UIViewAnimationOptionCurveLinear 
  |  UIViewAnimationOptionRepeat)
animations:^(void){
     wheel.transform = CGAffineTransformMakeRotation(M_PI*-0.5);
 }
completion:^(BOOL finished){
 if(finished){NSLog(@"^^^^^^^^wheel^^^^FINSIHED");
   ]}
}];

The problem I have is that on OS4 when the app has been dismissed to the multitasking bar and resumed the animation stops. If on resume I reset the position when the app becomes active again, like this....

wheel.transform = CGAffineTransformMakeRotation(0);

then it continues.

This isn't ideal because my animation skips when it restarts. I don't understand why this happens or why I should need to do this.

The "on finished" method gets called almost immediately 开发者_如何学JAVAas the animation starts which is odd as this animation should never finish. Also it DOES NOT get called when the app becomes active and the animation actually stops.

Anyone any ideas or suggestions? I'm been struggling with this for some time now...


You should either setup a timer using NSTimer or use CADisplaylink like so: displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateImages:)]; and change the rotation CGAffineTransformMakeRotation(degrees) of your view in the delegate method.


I'm having a similar problem. I was able to overcome this problem by turning off the ability for the app to run in the background by adding the key: "Application does not run in background" and setting it to YES in the info.plist. If your app does not need to run in the background and is OK if it is brought back to its initial state when resuming then this will work.


The syntax of your code is invalid; your code will not compile as shown. A correct version would be:

    [UIView animateWithDuration:2 delay:0.0
                    options:(UIViewAnimationOptionAllowUserInteraction |
                             UIViewAnimationOptionCurveLinear 
                             |  UIViewAnimationOptionRepeat)
                 animations:^(void){
                     wheel.transform = CGAffineTransformMakeRotation(M_PI*-0.5);
                 }
                 completion:^(BOOL finished){
                     if(finished) NSLog(@"^^^^^^^^wheel^^^^FINSIHED");
                 }
     ];

The reason why the "on finished" block is called when the app resumes after suspension and you set the animation going again is that the wheel's transform is already at its final position (this is where you set it in your animations block). So, when the app resumes, you must first reset the wheel's transform (I would do this by setting it to CGAffineTransformIdentity) and then set the animation going.

A smarter approach would be to use CGAffineTransformRotate (and not CGAffineTransformMakeRotation). That way, you can set the transform based on what the transform is now, rather than setting it absolutely.

    [UIView animateWithDuration:2 delay:0.0
                    options:(UIViewAnimationOptionAllowUserInteraction |
                             UIViewAnimationOptionCurveLinear 
                             |  UIViewAnimationOptionRepeat)
                 animations:^(void){
                     wheel.transform = CGAffineTransformRotate(view.transform, (M_PI*-0.5));
                 }
                 completion:^(BOOL finished){
                     // whatever
                 }
    ];

I presume that your wheel is symmetric with respect to your chosen angle, so the user will never see the difference, and the slip you're complaining about (when you reset the transform) will be eliminated.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜