使用 CAKeyframeAnimation 和路径时出现间歇性 fillMode=kCAFillModeForwards 错误

发布于 2024-08-24 14:10:54 字数 2073 浏览 11 评论 0原文

当我使用 CAKeyframeAnimation 在屏幕上移动 UIImageView 时,遇到间歇性问题。我希望 UIImageView 的位置保持在动画完成时结束的位置。此错误仅发生在某些起点和终点。当我使用随机点时,它在大多数情况下都能正常工作,但大约 5-15% 的情况下它会失败并恢复到动画前的位置。仅当使用 CAKeyframeAnimation 使用路径属性时才会出现该问题。如果我使用值属性,则不会出现错误。我设置removedOnCompletion = NO,并且fillMode = kCAFillModeForwards。我在下面发布了一个测试 Xcode 的链接。这是我设置动画的代码。我有一个属性 usePath.当这是“是”时,就会出现错误。当我将 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 并查看我的测试项目,请转到 测试项目 (http://www.24x7digital.com/downloads/PathFillModeBug.zip)

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

我使用的是 SDK 3.1.3,但我在使用 SDK 3.0 时也发现了此错误,并且我在 Sim 和 iPhone 上也看到了此错误。

任何有关如何解决此问题或我是否做错了什么的想法都将受到赞赏。谢谢,马克。

I'm having an intermittent problem when I move a UIImageView around the screen using CAKeyframeAnimation. I want the position of the UIImageView to remain where the animation ends when it is done. This bug only happens for certain start and end points. When I use random points it works correctly most of the time, but about 5-15% of the time it fails and snaps back to the pre-animation position. The problem only appears when using CAKeyframeAnimation using the path property. If I use the values property the bug does not appear. I am setting removedOnCompletion = NO, and fillMode = kCAFillModeForwards. I have posted a link to a test Xcode below. Here is my code for setting up the animation. I have a property usePath. When this is YES, the bug appears. When I set usePath to NO, the snap back bug does not happen. In this case I am using a path that is a simple line, but once I resolve this bug with a simple path, I will use a more complex path with curves in it.

// 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"];

To dl and view my test project goto test project (http://www.24x7digital.com/downloads/PathFillModeBug.zip)

Tap the 'Move Ball' button to start the animation of the ball. I have hard coded a start and end point which causes the bug to happen every time. Use the switch to change usePath to YES or NO. When usePath is YES, you will see the snap back bug. When usePath is NO, you will not see the snap back bug.

I'm using SDK 3.1.3, but I have seen this bug using SDK 3.0 as well, and I have seen the bug on the Sim and on my iPhone.

Any idea on how to fix this or if I am doing something wrong are appreciated. Thanks, Mark.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你不是我要的菜∠ 2024-08-31 14:10:54

在联系[email protected]后,他们确认Core中存在错误与带有路径的 kCAFillModeForwards 相关的动画。他们让我提交错误报告,我照做了(问题 ID:7797921)。

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

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

但在我的实际应用程序中,我设置了rotationMode = kCAAnimationRotateAuto,以便更新对象的z旋转以保持其与路径相切。因此,当发生快速恢复时,rotationMode z 旋转就会丢失。他们告诉我在animationDidStop:finished:中显式设置旋转,如下所示:

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

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

After contacting [email protected], they confirmed that there is a bug in Core Animation with respect to kCAFillModeForwards with paths. They told me to file a bug report which I did (Problem ID: 7797921).

They did try to give me a workaround. They said to set the end pt position right after I start the animation. This will keep the position from snapping back when the bug occurs:

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

But in my actual app I set rotationMode = kCAAnimationRotateAuto so that the objects z rotation is updated to keep it tangent to the path. So when the snap back occurs, the rotationMode z rotation is lost. They told me to set the rotation explicitly in animationDidStop:finished: like so:

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

This does not completely solve the problem because sometimes I get a flicker of the snap back rotation, and then the correction rotation. I'm hoping that they fix the fillMode = kCAFillModeForwards with paths bug.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文