我不是 100% 清楚你想要什么,但如果目标只是让整个笔画在绘制时改变颜色,但在三个离散的阶段,那么我建议添加以下内容。我在默认的“单一视图应用程序”模板中编写了这些示例。我设置了一个按钮,其动作指向-doStuff:
。如果整个笔触颜色发生变化,它可能看起来像这样:
为了产生它,代码看起来像:
@implementation MyViewController
{
CAShapeLayer* mLayer;
}
- (IBAction)doStuff:(id)sender
{
const NSUInteger numSegments = 3;
const CFTimeInterval duration = 2;
[mLayer removeFromSuperlayer];
mLayer = [[CAShapeLayer alloc] init];
mLayer.frame = CGRectInset(self.view.bounds, 100, 200);
mLayer.fillColor = [[UIColor purpleColor] CGColor];
mLayer.lineWidth = 12.0;
mLayer.lineCap = kCALineCapSquare;
mLayer.strokeEnd = 0.0;
mLayer.path = [[UIBezierPath bezierPathWithRect: mLayer.bounds] CGPath]; // This can be whatever.
[self.view.layer addSublayer: mLayer];
[CATransaction begin];
{
[CATransaction setAnimationDuration: duration];// Dynamic Duration
[CATransaction setCompletionBlock:^{ NSLog(@"Done"); }];
const double portion = 1.0 / ((double)numSegments);
NSMutableArray* values = [NSMutableArray arrayWithCapacity: numSegments];
NSMutableArray* times = [NSMutableArray arrayWithCapacity: numSegments + 1];
for (NSUInteger i = 0; i < numSegments; i++)
{
[values addObject: (__bridge id)[[UIColor colorWithHue: i * portion saturation:1 brightness:1 alpha:1] CGColor]];
[times addObject: @(i * portion)];
}
[times addObject: @(1.0)]; // Have to add this, otherwise the last value wont get used.
{
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath: @"strokeColor"];
animation.keyTimes = times;
animation.values = values;
animation.calculationMode = kCAAnimationDiscrete;
animation.removedOnCompletion = NO;
animation.timeOffset = 0;
animation.fillMode = kCAFillModeForwards;
[mLayer addAnimation: animation forKey: @"strokeColor"];
}
{
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: @"strokeEnd"];
animation.fromValue = @(0);
animation.toValue = @(1);
animation.removedOnCompletion = NO;
animation.timeOffset = 0;
animation.fillMode = kCAFillModeForwards;
[mLayer addAnimation: animation forKey: @"strokeEnd"];
}
}
[CATransaction commit];
}
@end
或者,如果目标是让笔画的三个不同部分,都具有不同的颜色,这会稍微复杂一些,但仍然可以使用相同的基本原理来完成。需要注意的一点是,如果没有自定义绘图,您CAShapeLayer
的 s 不能有超过一种笔触颜色 (AFAIK),因此您需要将其分解为几个子图层。
下一个示例将一个形状图层放入视图中,然后为笔划的每个部分添加子图层,并设置动画以使其显示为正在绘制一个单一的、多色的笔划,其中每个段都是一种单独的颜色。这大概是它的样子:
这是代码:
@implementation MyViewController
{
CAShapeLayer* mLayer;
}
- (IBAction)doStuff:(id)sender
{
const NSUInteger numSegments = 3;
const CFTimeInterval duration = 2;
[mLayer removeFromSuperlayer];
mLayer = [[CAShapeLayer alloc] init];
mLayer.frame = CGRectInset(self.view.bounds, 100, 200);
mLayer.fillColor = [[UIColor purpleColor] CGColor];
mLayer.lineWidth = 12.0;
mLayer.lineCap = kCALineCapSquare;
mLayer.path = [[UIBezierPath bezierPathWithRect: mLayer.bounds] CGPath]; // This can be whatever.
[self.view.layer addSublayer: mLayer];
[CATransaction begin];
{
[CATransaction setAnimationDuration: duration];//Dynamic Duration
[CATransaction setCompletionBlock:^{ NSLog(@"Done"); }];
const double portion = 1.0 / ((double)numSegments);
for (NSUInteger i = 0; i < numSegments; i++)
{
CAShapeLayer* strokePart = [[CAShapeLayer alloc] init];
strokePart.fillColor = [[UIColor clearColor] CGColor];
strokePart.frame = mLayer.bounds;
strokePart.path = mLayer.path;
strokePart.lineCap = mLayer.lineCap;
strokePart.lineWidth = mLayer.lineWidth;
// These could come from an array or whatever, this is just easy...
strokePart.strokeColor = [[UIColor colorWithHue: i * portion saturation:1 brightness:1 alpha:1] CGColor];
strokePart.strokeStart = i * portion;
strokePart.strokeEnd = (i + 1) * portion;
[mLayer addSublayer: strokePart];
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath: @"strokeEnd"];
NSArray* times = @[ @(0.0), // Note: This works because both the times and the stroke start/end are on scales of 0..1
@(strokePart.strokeStart),
@(strokePart.strokeEnd),
@(1.0) ];
NSArray* values = @[ @(strokePart.strokeStart),
@(strokePart.strokeStart),
@(strokePart.strokeEnd),
@(strokePart.strokeEnd) ];
animation.keyTimes = times;
animation.values = values;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[strokePart addAnimation: animation forKey: @"whatever"];
}
}
[CATransaction commit];
}
@end
我不确定我是否完全理解您的目的,但希望其中之一对您有所帮助。