iPhone animation problem SImulator vs Real Device
This is my first question h开发者_Go百科er so please be gentle: I have followig animation code running smoothly on the simulator as well as on the real device (I am testng on iPhone 3GS 3.1.2). Animation is a simple transition between the 2 views, something like book page flipping.
One diffrence betwen simulator an real device (The problem I cannot investigate - solve) is that on real device when animation finishes - after rotation has been done animated view blink (show for a split of second) for a moment before it goes hidden. On the simulator this 'unexpected' blink does not happen.
Here is the animation code:
-(void)flip{
UIView *animatedView;
// create an animation to hold the page turning
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.removedOnCompletion = NO;
transformAnimation.delegate = self;
transformAnimation.duration = ANIMATION_TIME;
transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// this is the basic rotation by 90 degree along the y-axis
CATransform3D endTransform = CATransform3DMakeRotation(3.141f/2.0f,
0.0f,
-1.0f,
0.0f);
// these values control the 3D projection outlook
endTransform.m34 = 0.001f;
endTransform.m14 = -0.0015f;
// start the animation from the current state
transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
transformAnimation.toValue = [NSValue valueWithCATransform3D:endTransform];
animatedView = screenShot;
// Create an animation group to hold the rotation and possibly more complex animation in the future
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
// Set self as the delegate to receive notification when the animation finishes
theGroup.delegate = self;
theGroup.duration = ANIMATION_TIME;
// CAAnimation-objects support arbitrary Key-Value pairs, we add the UIView tag
// to identify the animation later when it finishes
[theGroup setValue:[NSNumber numberWithInt:animatedView.tag] forKey:@"animated"];
// Here you could add other animations to the array
theGroup.animations = [NSArray arrayWithObjects:transformAnimation,nil];
theGroup.removedOnCompletion = NO;
// Add the animation group to the layer
if (animatedView.layer.anchorPoint.x != 0.0f)
{
animatedView.layer.anchorPoint = CGPointMake(0.0f, 0.5f);
float yy = animatedView.center.x - (animatedView.bounds.size.width / 2.0f);
animatedView.center = CGPointMake(yy, animatedView.center.y);
}
if(![animatedView isDescendantOfView:self.view])[self.view addSubview:animatedView];
screenShot.hidden = NO;
animatedView.hidden = NO;
[animatedView.layer addAnimation:theGroup forKey:@"flip"];
}
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
screenShot.hidden = YES;
}
Try setting theGroup's and / or transformAnimation's fillMode to kCAFillModeForwards:
theGroup.fillMode = kCAFillModeForwards;
This should cause your animation to persist once its active duration has completed. I've used this to remove an end-of-animation flicker before.
Not sure I understand completely what you are seeing but it's possible you're seeing something caused by the speed difference between the device and the simulator. The simulator is considerably faster than the device so something that "blinks" very quickly might do so too fast for the human eye to catch on the simulator.
Oof. That's annoying. I think it is that there's a split-second between when animation stops and when that line of code executes. If only there were an animationWillStop:
method! You might try, instead of screenShot.hidden = YES
, screenShot.alpha = 0
. I doubt it will make any difference speed-wise, but it might be worth a shot? You could also fade out the view as part of the animation, but I don't think you want to do that.
The only other thing I can think of is to setup an NSTimer
with an interval just under your animation time. Something like:
[NSTimer scheduledTimerWithTimeInterval:(ANIMATION_TIME - .001) target:self selector:@selector(hideTheView) userInfo:nil repeats:NO];
And then implement that hideTheView
method, of course.
精彩评论