【iOS】自定义CALayer可能会出现没有动画过程但有动画结果的解析
按照计划是要做成这样的动画
可是结果变成了这样
(有时候最重要的不是结果而是过程,日常鸡汤)
结果没有问题说明delegate中- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
成功执行,故此文不做讨论
让我们看看自定义的CALAyer的代码
- (void)drawInContext:(CGContextRef)ctx {
// self.lineWidth = 2;
self.endAngle = 360;
self.startAngle = 0;
CGFloat sColorR = 94.0 / 256;
CGFloat sColorG = 127.0 / 256;
CGFloat sColorB = 242.0 / 256;
CGFloat sColorA = 1;
CGFloat radius = self.bounds.size.width / 2;
CGFloat lineWidth = self.lineWidth;
UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius - lineWidth / 2 startAngle:self.startAngle * M_PI * 2 / 360 endAngle:(self.endAngle == 0 ? 360 : self.endAngle) / 360 * M_PI * 2 * self.progress clockwise:YES];
CGContextSetRGBStrokeColor(ctx, sColorR, sColorG, sColorB, sColorA);//笔颜色
CGContextSetLineWidth(ctx, lineWidth);//线条宽度
CGContextAddPath(ctx, path.CGPath);
CGContextStrokePath(ctx);
}
- (instancetype)initWithLayer:(CircleProgressLayer *)layer {
if (self = [super initWithLayer:layer]) {
self.progress = layer.progress;
}
return self;
}
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqualToString:@"progress"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
@end
看来貌似是self.lineWidth
没有赋值的原因,那么这个时候我又分为两种情况来进行试着解决。
- 在
drawInContext()
方法内对其赋值,结果有效。 - 在
CALayer
外对其赋值,居然还是回到了之前错误的状况。
从方法的复用性来讲我们肯定提倡使用第二种方式对属性进行修改,所以在drawInContext()
中我打了断点,如同设想中的一样,每进行一次动画的时候,该方法会调用几次,同时每次调用的时候我还发现了一件极其有趣的事情。
可以看到,每次调用方法的时候,self的指针都发现了不同程度的变化,而在使用CALayer的时候我肯定不会做重复init这么傻的事情的。所以可以推测出,在执行动画的过程中,iOS会一直在init新的CALayer,以期达到“动”画的效果直到动画结束。
所以可以推测出,没有动画过程的问题是在于“动”的过程中有些固定参数没有传达到新的init的CALayer上。那么我们应该要怎么传达原有CALayer的参数呢?
- (instancetype)initWithLayer:(CircleProgressLayer *)layer {
if (self = [super initWithLayer:layer]) {
self.progress = layer.progress;
self.lineWidth = layer.lineWidth;
}
return self;
}
也就是晚上之前的init方法就可以让原layer的参数一份不落地传递过来了,以上。
本文来自博客园,作者:MrYu4,转载请注明原文链接:https://www.cnblogs.com/MrYU4/p/15778884.html