首页 文章

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

提问于
浏览
3

我通过创建一个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 回答

  • 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];
    

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

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

相关问题