8

当我创建显式动画以将 CAShapeLayer 路径的值从椭圆更改为矩形时,我遇到了问题。

在我的画布控制器中,我设置了一个基本的 CAShapeLayer 并将其添加到根视图的层:

CAShapeLayer *aLayer;
aLayer = [CAShapeLayer layer];
aLayer.frame = CGRectMake(100, 100, 100, 100);
aLayer.path = CGPathCreateWithEllipseInRect(aLayer.frame, nil);
aLayer.lineWidth = 10.0f;
aLayer.strokeColor = [UIColor blackColor].CGColor;
aLayer.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:aLayer];

然后,当我为路径设置动画时,当形状变为矩形时,动画的最后几帧中会出现奇怪的故障/闪烁,而在动画远离矩形的前几帧中会出现奇怪的故障/闪烁。动画设置如下:

CGPathRef newPath = CGPathCreateWithRect(aLayer.frame, nil);
[CATransaction lock];
[CATransaction begin];
[CATransaction setAnimationDuration:5.0f];
CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"path"];
ba.autoreverses = YES;
ba.fillMode = kCAFillModeForwards;
ba.repeatCount = HUGE_VALF;
ba.fromValue = (id)aLayer.path;
ba.toValue = (__bridge id)newPath;
[aLayer addAnimation:ba forKey:@"animatePath"];
[CATransaction commit];
[CATransaction unlock];

我尝试了许多不同的事情,例如锁定/解锁 CATransaction,使用各种填充模式等...

这是故障的图像: http ://www.postfl.com/outgoing/renderingglitch.png

我正在经历的视频可以在这里找到:http: //vimeo.com/37720876

4

2 回答 2

8

我收到了来自quartz-dev 列表的反馈:

大卫邓肯写道:

仅当您从喜欢到喜欢制作动画时,才能保证为形状图层的路径设置动画。矩形是一系列线,而椭圆是一系列弧(您可以看到使用 CGPathApply 生成的序列),因此不能保证它们之间的动画看起来非常好,或者根本无法正常工作。

为此,您基本上必须使用与创建椭圆相同的曲线来创建一个矩形的模拟,但使用的参数会使渲染看起来像一个矩形。这应该不会太难(同样,您可以使用从 CGPathApply 获得的内容在使用 CGPathAddEllipseInRect 创建的路径上作为指导),但可能需要进行一些调整才能正确。

于 2012-03-01T19:40:10.723 回答
5

不幸的是,这是对 CAShapeLayers 原本很棒的动画路径属性的限制。

基本上它试图在两条路径之间进行插值。当目标路径和起始路径具有不同数量的控制点时,它会遇到麻烦 - 曲线和直边会有这个问题。

您可以尝试通过将椭圆绘制为 4 条曲线而不是单个椭圆来尽量减少影响,但这仍然不太正确。我还没有找到一种从曲线平滑到多边形的方法。

您可能能够获得大部分的方式,然后转移到最后一部分的淡入淡出动画 - 但是这看起来不太好。

于 2012-03-01T08:50:47.997 回答