跟踪CAShapeLayer的strokeEnd点的方法?

时间:2014-07-28 13:16:53

标签: objective-c core-animation uibezierpath cgpath cashapelayer

我的问题涉及跟踪CAShapeLayer的strokeEnd点坐标的可能性。

我有一个UISlider,它生成一个介于0和1之间的变量。 我从CGMutablePathRef创建一个UIBezierPath,并将其指定为CAShapeLayer的path属性。

这是我的头文件:

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UISlider *progressSlider;
@property (strong,nonatomic) CAShapeLayer *raceTrack;
- (IBAction)progressChanged:(id)sender;
@end

在实现文件中,我编写了以下代码:

CGMutablePathRef truePath = CGPathCreateMutable();
CGPathMoveToPoint(truePath, NULL, 100.0f, 468.0f-20.0f);
CGPathAddQuadCurveToPoint(truePath, NULL, 70.0f, 268.0f, 100.0f, 68.0f+20.0f);

UIBezierPath *trackPath = [UIBezierPath bezierPathWithCGPath:truePath];

self.raceTrack = [CAShapeLayer layer];
self.raceTrack.path = trackPath.CGPath;
self.raceTrack.strokeEnd = 0.0;
self.raceTrack.strokeColor = [UIColor yellowColor].CGColor;
self.raceTrack.fillColor = [UIColor clearColor].CGColor;
self.raceTrack.lineWidth = 7.0;
[self.view.layer addSublayer:self.raceTrack];

每次更改滑块时,都会调用以下函数:

- (IBAction)progressChanged:(id)sender{
self.raceTrack.strokeEnd = self.progressSlider.value;}

这完美无缺!但现在我想在屏幕上绘制的行尾添加一种圆圈。 我无法发布图像,但是如果你想了解我们可能会认为圆圈是彗星并且在它后面,则描边路径是彗星的尾部。

我不知道如何实现这一目标。我想也许最好的方法是跟踪笔画终点的坐标,并添加一个带addSublayer的圆圈,并设置此圆的位置属性等于strokeEnd点的坐标。我不知道是否存在这样的strokeEnd点或者是否有一个简单的解决方案,你们中的一个用于此类问题。

这就是为什么我第一次请求你的帮助。

1 个答案:

答案 0 :(得分:1)

据我所知,你必须从二次贝塞尔曲线的公式计算点。这段代码就是这样做的,

- (IBAction)progressChanged:(UISlider *)sender{
    self.raceTrack.strokeEnd = sender.value;
    CGPoint strokeEnd = [self pointAtStrokeEnd:sender.value]; 
}


-(CGPoint)pointAtStrokeEnd:(CGFloat) fraction {

    CGFloat x = (1 - fraction) * (1 - fraction) * self.startPoint.x + 2 * (1 - fraction) * fraction * self.controlPoint.x + fraction * fraction * self.endPoint.x;
    CGFloat y = (1 - fraction) * (1 - fraction) * self.startPoint.y + 2 * (1 - fraction) * fraction * self.controlPoint.y + fraction * fraction * self.endPoint.y;
    return CGPointMake(x, y);
}

您需要为曲线的起点,终点和控制点创建属性或ivars,以便将它们传递给pointAtStrokeEnd:方法。