我可以为UIBezierPath添加自定义线路上限吗?

时间:2013-12-03 15:29:08

标签: ios objective-c core-animation uibezierpath

我正在通过创建一个CAShapeLayer并给它一个像这样的Bezier路径绘制一个弧:

self.arcLayer = [CAShapeLayer layer];
UIBezierPath *remainingLayerPath = [UIBezierPath bezierPathWithArcCenter:self.center
                                                                  radius:100
                                                              startAngle:DEGREES_TO_RADIANS(135)
                                                                endAngle:DEGREES_TO_RADIANS(45)
                                                               clockwise:YES];
self.arcLayer.path = remainingLayerPath.CGPath;
self.arcLayer.position = CGPointMake(0,0);

self.arcLayer.fillColor = [UIColor clearColor].CGColor;
self.arcLayer.strokeColor = [UIColor blueColor].CGColor;
self.arcLayer.lineWidth = 15;

这一切都运行良好,我可以轻松地将弧从一侧动画到另一侧。就目前而言,这为我的线条末端提供了一个非常方形的边缘。我可以使用自定义半径(例如3(线宽的三分之一))绕过这些线帽的边缘吗?我玩lineCap属性,但唯一真正的选项似乎是完全平方或圆角,角半径大于我想要的。我也尝试了图层上的cornerRadius属性,但它似乎没有任何影响(我假设因为线帽不被视为实际的图层角)。

我只能想到两个真正的选择,我对其中任何一个都不感兴趣。我可以想出一个完全自定义的Bezier路径,跟踪弧形外部,完成我自定义的圆形边缘。然而,我担心能够以相同的方式为弧设置动画(现在我只是将笔划从0设置为1)。另一种选择是让端盖成方形并遮盖角落,但我的理解是掩模相对昂贵,而且我打算用这个视图做一些相当密集的动画。

任何建议都会有所帮助。提前谢谢。

1 个答案:

答案 0 :(得分:1)

我最终通过创建两个完全独立的层来解决这个问题,一个用于左端盖,另一个用于右端盖。这是右端帽示例:

self.rightEndCapLayer = [CAShapeLayer layer];
CGRect rightCapRect = CGRectMake(remainingLayerPath.currentPoint.x, remainingLayerPath.currentPoint.y, 0, 0);
rightCapRect = CGRectInset(rightCapRect, self.arcWidth / -2, -1 * endCapRadius);
self.rightEndCapLayer.frame = rightCapRect;
self.rightEndCapLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.rightEndCapLayer.bounds
                                                   byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight
                                                         cornerRadii:CGSizeMake(endCapRadius, endCapRadius)].CGPath;
self.rightEndCapLayer.fillColor = self.remainingColor.CGColor;

// Rotate the end cap
self.rightEndCapLayer.anchorPoint = CGPointMake(.5, 0);
self.rightEndCapLayer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(45), 0.0, 0.0, 1.0);

[self.layer addSublayer:self.rightEndCapLayer];

使用bezier路径的当前点可以节省大量的数学运算来计算终点应该出现的位置。移动锚点还允许图层不重叠,这在弧完全透明时很重要。

这仍然不完全理想,因为动画必须通过多个层链接。这比我能提出的替代方案要好。