Круг обводкиИзменение ширины анимации без изменения радиуса круга - PullRequest
1 голос
/ 14 апреля 2020

У меня есть несколько строк, в которых я рисую круг с UIBezierPath и CAShapeLayer. Они должны действовать как кнопки, в которых при нажатии они выбираются, а при нажатии другой кнопки они отменяются, при этом каждое из этих состояний должно изменять внешний вид кнопки между этими двумя условиями:

отменено: 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];

Когда этот прямоугольник выделен, я хотел бы изменить ширину штриха круга только внутрь и сохранить первоначальный радиус. Когда он отменен, должно произойти обратное. Как вы можете видеть, я изменяю как радиус, так и lineWidth, потому что, когда я увеличиваю значение strokeWidth, увеличивается и внешний радиус. И, как я уже сказал, я хочу, чтобы это оставалось неизменным.

Проблема в том, что я хочу, чтобы он анимировался таким образом, чтобы ширина увеличивалась внутрь при выборе и наружу при отмене выбора, без изменения внешнего радиуса вообще , Пока что у меня есть анимация изменения strokeWidth вместе с радиусом, чтобы сохранить результат с таким же радиусом. Но это не то, что мне нужно. Как видите, здесь анимируется только изменение радиуса, и в результате получается растущий круг, который мне не нужен.

enter image description here

This это код анимации (в дополнение к исходному коду):

  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. Это также не делает то, что мне нужно. Есть ли способ, чтобы штрих ширины увеличивался или уменьшался без изменения внешнего радиуса?

Вот так: enter image description hereenter image description hereenter image description here

1 Ответ

1 голос
/ 14 апреля 2020

Благодаря @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

...