问题
I've got a CAShapeLayer subclass which features two properties, a startPoint and an endPoint. These properties aren't directly drawn into the context but rather used to alter the path property, similar to the transform, position and bounds properties.
Here's the code of the whole layer
-(void)setStartPoint:(CGPoint)startPoint {
if (!CGPointEqualToPoint(_startPoint, startPoint)) {
_startPoint = startPoint;
[self reloadPath];
}
}
-(void)setEndPoint:(CGPoint)endPoint {
if (!CGPointEqualToPoint(_endPoint, endPoint)) {
_endPoint = endPoint;
[self reloadPath];
}
}
-(id)initWithLayer:(CRPathLayer*)layer {
self = [super initWithLayer:layer];
if (self && [layer isKindOfClass:[CRPathLayer class]]) {
self.startPoint = layer.startPoint;
self.endPoint = layer.endPoint;
}
return self;
}
+(BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqualToString:NSStringFromSelector(@selector(startPoint))] || [key isEqualToString:NSStringFromSelector(@selector(endPoint))]) {
return YES;
}
return [super needsDisplayForKey:key];
}
-(void)reloadPath {
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.startPoint.x, self.startPoint.y);
CGPathAddLineToPoint(path, NULL, self.endPoint.x, self.endPoint.y);
self.path = path;
CGPathRelease(path);
}
However there's a problem. I need to animate one of the two new properties (start- or endPoint). I'm aware of the fact that I could just animate the path property directly, however this is not what I want to achieve. I'm obviously missing something in the implementation. When I try to animate it using a CABasicAnimation nothing happens at all.
Can anybody help me out here? Thanks in advance.
回答1:
The piece you are missing is the actionForKey:
method (and that while the path
is animatable, it's not implicitly animatable (i.e. it won't animate just because the property changes)).
What you have to do is to supply an action (a more general term for an animation) for the path whenever the startPoint or endPoint changes (or just make the path implicitly animatable so that setting a new path causes an animation, they really do the same thing).
It could looks something like this (I typed this out in the browser so it may not compile):
- (id <CAAction>)actionForKey:(NSString *)key
{
if ([key isEqualToString:@"startPoint"] || [key isEqualToString:@"endPoint")]) {
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"path"];
anim.fromValue = [self.presentationLayer valueFoKey:@"path"];
return animo;
}
return [super valueForKey:key];
}
来源:https://stackoverflow.com/questions/22744172/animate-a-cashapelayers-subclass-custom-property-based-on-the-path-property