Как остановить / отменить анимацию прогресса UIProgressView?

У меня есть UIProgressView, который должен быть обновлен, пока пользователь держит кнопку. Для плавной анимации я решил использовать UIView.animateWithDuration вместо таймера для обновления прогресса.

Чего я ожидаю добиться, так это: прогресс увеличивается, пока пользователь удерживает кнопку, достигая 100% за 30 секунд (а затем останавливается). Если пользователь отпускает кнопку до истечения времени, индикатор выполнения просто останавливается в текущем ходе. Если пользователь затем снова удерживает кнопку, прогресс сбрасывается до нуля, и тот же процесс повторяется снова и снова.

Проблема в том, что я не могу отменить анимацию, когда пользователь отпускает кнопку. Я пытался использовать progressView.layer.removeAllAnimation(), но тоже не сработало.

Ниже - мой код:

@IBAction func holdValueChanged(_ sender: CustomButton) {        
    if sender.isPressed {
        progressView.progress = 1.0

        UIView.animate(withDuration: 30.0, delay: 0.0, options: UIViewAnimationOptions.curveLinear, animations: { 
            self.progressView.layoutIfNeeded()
            }, completion: { (finished) in
                print("Ended progress animation")
        })
    }
    else {
        // stop progress animation
        progressView.layer.removeAllAnimations()
    }
}

1 ответ

На самом деле это потому, что нет никакой гарантии, что анимируемый слой - progressView.layer. Вот почему progressView.layer.removeAllAnimations() не будет работать. Попробуйте этот подход:

for (CALayer *layer in self.progressBar.layer.sublayers) {
    [layer removeAllAnimations];
}

Попробуйте создать вторую (короткую) анимацию из текущего состояния до желаемой точки остановки, например, что-то вроде этого (не проверено):

UIView.animate(withDuration: 0.1, delay: 0,
               options: [ .beginFromCurrentState, .allowUserInteraction ],
               animations: {
    self.progressView.progress = 1.0; // or whatever state it stopped at
}, completion:nil);

Запуск новой анимации должен отменить все существующие, и .beginFromCurrentState предотвратит его прыжки до конца (если вы хотите закончить в какой-то другой точке). В качестве бонуса визуальный эффект короткой анимации также может быть приятнее, чем просто отмена.

Другие вопросы по тегам