Перерисовать UIBezierPath на основе случайного значения CGFloat

Я разрабатываю собственный круговой индикатор выполнения, используя UIBezierPath. Я хочу изменить прогресс на основе случайно сгенерированных значений CGFloat.

Мой индикатор выполнения выглядит так:

введите здесь описание изображения

Я нарисовал индикатор выполнения, используя следующий код:

 // Draw the arc with bezier path
    int radius = 100;

    CAShapeLayer *arc = [CAShapeLayer layer];
    arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:M_PI endAngle:M_PI/150 clockwise:YES].CGPath;
    arc.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
                                CGRectGetMidY(self.view.frame)-radius);
    arc.cornerRadius = 100.0;
    arc.fillColor = [UIColor clearColor].CGColor;
    arc.strokeColor = [UIColor purpleColor].CGColor;
    arc.lineWidth = 6;

    [self.view.layer addSublayer:arc];

    // Animation of the progress bar
    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawAnimation.duration            = 5.0; // "animate over 10 seconds or so.."
    drawAnimation.repeatCount         = 1.0;  // Animate only once..
    drawAnimation.removedOnCompletion = YES;   // Remain stroked after the animation..
    drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    drawAnimation.toValue   = [NSNumber numberWithFloat:10.0f];
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];

    // Gradient of progress bar
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.view.frame;
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor yellowColor].CGColor,(__bridge id)[UIColor purpleColor].CGColor ];
    gradientLayer.startPoint = CGPointMake(0,0.1);
    gradientLayer.endPoint = CGPointMake(0.5,0.2);
    [self.view.layer addSublayer:gradientLayer];
    gradientLayer.mask = arc;

    refreshButton = [[UIButton alloc] initWithFrame:CGRectMake(50, 370, 50, 50)];
    [refreshButton addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventTouchUpInside];
    [refreshButton setBackgroundImage:[UIImage imageNamed:@"refresh.png"] forState:UIControlStateNormal];
    [self.view addSubview:refreshButton];

Кнопка UIButton с зеленой стрелкой генерирует случайные значения CGFloat. Итак, мой вопрос: как сбросить анимацию, чтобы она остановилась в соответствующей позиции, если она находится между 0,0 и 1,0? Я пытался вставить код анимации внутрь метода кнопки, но в результате новая дуга рисовалась поверх существующей.

-(void)refresh:(id)sender{
    NSLog(@"Refresh action:");
    CGFloat randomValue = ( arc4random() % 256 / 256.0 );
    NSLog(@"%f", randomValue);

    valueLabel.text = @"";
    valueLabel = [[UILabel alloc] initWithFrame:CGRectMake(150, 370, 100, 50)];
    valueLabel.text = [NSString stringWithFormat: @"%.6f", randomValue];
    [self.view addSubview:valueLabel];

    // Draw the arc with bezier path
    int radius = 100;

    CAShapeLayer *arc = [CAShapeLayer layer];
    arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:M_PI endAngle:M_PI/150 clockwise:YES].CGPath;
    arc.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
                               CGRectGetMidY(self.view.frame)-radius);
    arc.cornerRadius = 100.0;
    arc.fillColor = [UIColor clearColor].CGColor;
    arc.strokeColor = [UIColor purpleColor].CGColor;
    arc.lineWidth = 6;

    [self.view.layer addSublayer:arc];

    // Animation of the progress bar
    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawAnimation.duration            = 5.0; // "animate over 10 seconds or so.."
    drawAnimation.repeatCount         = 1.0;  // Animate only once..
    drawAnimation.removedOnCompletion = YES;   // Remain stroked after the animation..
    drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    drawAnimation.toValue   = [NSNumber numberWithFloat:randomValue];
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];


}

Я понятия не имею, как перерисовать дугу, поэтому любая помощь или идея будут очень признательны!

Большое спасибо.

Гранит


person Granit    schedule 17.12.2013    source источник
comment
первое предложение: ваш valueLabel рисуется поверх самого себя. Старайтесь не создавать его заново при каждом обновлении, а просто меняйте его текст. Во-вторых, попробуйте повторно использовать подслой или заменить его. Сделайте arc переменной класса. Затем прокрутите подслои, удалите старый arc, а затем переделайте его с новым случайным процентом поплавка. Как только arc станет переменной класса, вы можете либо заменить ее и анимировать с нуля, либо вы можете анимировать от текущего процента до нового процента.   -  person Putz1103    schedule 17.12.2013
comment
@ Putz1103 Putz1103 Я сделал arc переменной класса, перерисовываю круг, и он работает. Не могли бы вы ответить, чтобы я мог принять? :) Спасибо   -  person Granit    schedule 17.12.2013


Ответы (1)


Попробуйте повторно использовать подслой или заменить его. Сделайте arc переменной класса. Затем прокрутите подслои, удалите старую дугу, а затем переделайте ее с новым случайным процентом поплавка. Как только дуга является переменной класса, вы можете либо заменить ее и анимировать с нуля, либо вы можете анимировать от текущего процента до нового процента.

person Putz1103    schedule 17.12.2013