使用CAKeyframeAnimation和path的间歇fillMode = kCAFillModeForwards错误

时间:2010-03-12 23:47:32

标签: iphone core-animation iphone-sdk-3.0 cakeyframeanimation

当我使用CAKeyframeAnimation在屏幕上移动UIImageView时,我遇到了间歇性问题。我希望UIImageView的位置保持在动画完成时结束的位置。此错误仅发生在某些起点和终点。当我使用随机点时,它大部分时间都能正常工作,但大约有5-15%的时间失败并快速回到动画前的位置。只有在使用路径属性使用CAKeyframeAnimation时才会出现此问题。如果我使用values属性,则不会出现错误。我设置removedOnCompletion = NO,并且fillMode = kCAFillModeForwards。我在下面发布了一个测试Xcode的链接。这是我设置动画的代码。我有一个属性usePath。如果是YES,则会出现错误。当我将usePath设置为NO时,不会发生快照错误。在这种情况下,我使用的是一条简单的路径,但是一旦我用一条简单的路径解决了这个错误,我将使用一条带有曲线的更复杂的路径。

// create the point        
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
if (self.usePath) {
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, startPt.x, startPt.y);
    CGPathAddLineToPoint(path, NULL, endPt.x, endPt.y);
    moveAnimation.path = path;
    CGPathRelease(path);    
} else {
    moveAnimation.values = [NSArray arrayWithObjects:
                            [NSValue valueWithCGPoint:startPt],
                            [NSValue valueWithCGPoint:endPt],
                            nil];
}
moveAnimation.calculationMode = kCAAnimationPaced;
moveAnimation.duration = 0.5f;
moveAnimation.removedOnCompletion = NO;
// leaves presentation layer in final state; preventing snap-back to original state
moveAnimation.fillMode = kCAFillModeForwards; 
moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
// moveAnimation.delegate = self;    

// start the animation
[ball.layer addAnimation:moveAnimation forKey:@"moveAnimation"];

要dl并查看我的测试项目goto test projecthttp://www.24x7digital.com/downloads/PathFillModeBug.zip

点击“移动球”按钮开始球的动画。我已经硬编码了一个起点和终点,每次都会导致bug发生。使用开关将usePath更改为YES或NO。当usePath为YES时,您将看到快照错误。当usePath为NO时,您将看不到快照错误。

我正在使用SDK 3.1.3,但我也看到了使用SDK 3.0的这个错误,我在Sim和我的iPhone上看到了这个错误。

任何关于如何解决这个问题的想法或者如果我做错了什么都会受到赞赏。谢谢,马克。

1 个答案:

答案 0 :(得分:7)

在联系idp-dts@apple.com后,他们确认Core Animation中存在与路径有关的kCAFillModeForwards的错误。他们告诉我提交我做的错误报告(问题ID:7797921)。

他们确实试图给我一个解决方法。他们说我在开始动画后立即设置了结束位置。这将阻止该位置在发生错误时回弹:

// start the animation
[ball.layer addAnimation:moveAnimation forKey:@"moveAnimation"];
ball.layer.position = endPt;

但是在我的实际应用程序中,我设置了rotationMode = kCAAnimationRotateAuto,以便更新对象z rotation以使其与路径相切。因此,当发生快照时,rotationMode z旋转将丢失。他们告诉我在animationDidStop中明确设置旋转:完成:像这样:

[ball.layer setValue:[NSNumber numberWithDouble:-M_PI/2.0] forKeyPath:@"transform.rotation.z"];

这并不能完全解决问题,因为有时我会获得回弹旋转的闪烁,然后是修正旋转。我希望他们用路径错误修复fillMode = kCAFillModeForwards。