圆笔触宽度更改动画而不更改圆半径

时间:2020-04-14 07:48:17

标签: ios objective-c uibezierpath cashapelayer cabasicanimation

我有几个矩形,分别用UIBezierPathCAShapeLayer画一个圆。它们应该像按钮一样工作,在其中轻击它们时将其选中,而在轻按一个不同的按钮时它们将被取消选择,其中每种状态均应在这两种情况之间改变按钮的外观:

已取消选择:original已选择:enter image description here

这是常规代码(选择更改时会调用):

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];

选择此矩形后,我只想向内更改圆的strokeWidth,并保持原始半径。取消选择它时,相反的情况会发生。 如您所见,我同时更改了半径和lineWidth,因为当我增大strokeWidth时,外半径也随之增大。正如我所说,我想保持不变。

问题是我希望它以某种动画方式显示,使其宽度在选定时向内增大,在取消选定时向外增大,而根本不改变外半径。 到目前为止,我得到的是strokeWidth和半径变化的动画,以使结果保持相同的出现半径。但这不是我所需要的。如您所见,此处仅对半径变化进行了动画处理,结果是一个不断增大的圆,这不是我想要的。

enter image description here

这是动画的代码(除了原始代码):

  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增大或减小?

像这样:enter image description here enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

感谢@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];

enter image description here