Circle strokeWidth改变动画不改变圆半径

Circle strokeWidth change animation without changing the circle radius

我有几个矩形,我用 UIBezierPathCAShapeLayer 画了一个圆圈。它们应该像按钮一样,当它们被点击时,它们被选中,当不同的按钮被点击时,它们被取消选择,其中每个状态都应该在这两种情况之间改变按钮外观:

取消选择: selected:

这是通用代码(选择更改时调用):

CGFloat radius = isSelected ? 9.8 : 13. ;
CGFloat strokeWidth = isSelected ? 10.5 : 2;

UIBezierPath *bezierPath = [UIBezierPath bezierPath];
CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
[bezierPath addArcWithCenter:center radius:radius startAngle:0 endAngle:2 * M_PI clockwise:YES];

CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:[UIColor redColor].CGColor];
[progressLayer setLineWidth:strokeWidth]];
[self.layer addSublayer:progressLayer];

选中这个rec​​t后,我想只改变圆的strokeWidth向内,保持原来的半径。当它被取消选择时,应该发生相反的情况。 如您所见,我同时更改了半径和线宽,因为当我增大 strokeWidth 时,外半径也会增加。正如我所说,我想保持不变。

问题是我希望它的动画效果是选中时宽度向内增长,取消选中时宽度向外增长,根本不改变外半径。 到目前为止,我所拥有的是 strokeWidth 与半径一起变化的动画,以保持出现的半径相同的结果。但这不是我需要的。正如你所看到的,这里只有半径的变化是动画的,结果是一个越来越大的圆,这是我不想要的。

这是动画的代码(加上原代码):

  CABasicAnimation *changeCircle = [CABasicAnimation animationWithKeyPath:@"path"];
  changeCircle.duration = 0.6;
  changeCircle.fromValue = (__bridge id)oldPath; // current bezier path
  changeCircle.toValue = (__bridge id)newPath; // new bezier path

  [progressLayer addAnimation:changeCircle forKey:nil];

我也有相反的代码,它只对 strokeWidth 的变化进行动画处理。它也不能满足我的需要。 有没有办法在不改变外半径的情况下使 strokeWidth 变大或变小?

像这样:

感谢@Chris,我设法解决了这个问题。

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id) oldPath;
pathAnimation.toValue = (__bridge id) newPath;

CABasicAnimation *lineWidthAnimation = [CABasicAnimation animationWithKeyPath:@"lineWidth"];
lineWidthAnimation.fromValue = isSelected ? @2. : @10.5;
lineWidthAnimation.toValue = isSelected ? @10.5 : @2.;

CAAnimationGroup *group = [CAAnimationGroup animation];
group.duration = 0.3;
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
group.animations = @[pathAnimation, lineWidthAnimation];

CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:self.color.CGColor];
[progressLayer setLineWidth:isSelected ? 10.5 : 2];
[progressLayer setFillColor:[UIColor clearColor].CGColor];
[progressLayer addAnimation:group forKey:@"selectedAnimations"];
[self.layer addSublayer:progressLayer];