У меня есть UIView
подкласса, который отображает круговую прогресс:UIView с пользовательским DrawRect и animateWithDuration
Скриншот выше показывает прогресс со значением 0.667
.
Внутри моей реализации UIView
подкласс в drawRect:
метод Я рисую два круга - один для фона овальный (серый), второй для фактического прогресса овальный (синий). (Check out source code)
Работает так, как ожидалось, но не позволяет анимировать изменения прогресса. Я пытался найти решение, которое позволяет с помощью метода animateWithDuration:animations:
класса UIView
«S, как это:
MyCustomView *progressView = ...
[UIView animateWithDuration:3
animations:^{
progressView.progressValue = 1.f;
}];
Но я не был в состоянии сделать это воодушевляет тот путь.
Вы можете проверить исходный код в my GitHub repository.
Тем не менее, я нашел способ выполнить анимацию при изменении progressValue
. Это не совсем то, что я хочу (все еще не работает с UIView
animateWithDuration:animations:
), и я не уверен, что это правильное направление. Он включает подклассификацию CALayer
моего UIView
. Вы можете проверить исходный код в том же репо, упомянутом выше, on custom_layer branch. Вот direct link до CALayer
реализация подкласса подкласса.
Моего вопрос: Имея UIView
подкласс, который рисует несколько фигур на основе пользовательских свойств (progressValue
), можно сделать вид одушевляет с UIView
«s animateWithDuration:animations:
при изменении свойства представления (progressValue
)?
UPDATE
Благодаря rounak's answer избавиться от рисования пользовательских форм в drawRect:
метод и создал два отдельных CAShapeLayer
с. Вместо того, чтобы рисовать новые фигуры каждый раз, когда меняются progressValue
, я просто устанавливаю свойства strokeEnd
для этих слоев, что дает тот же визуальный эффект, что и раньше, но должен работать лучше (check out source code).
Тогда я реализовал actionForLayer:forKey:
метод (check out source code), который возвращает CABasicAnimation
, которые должны анимировать strokeEnd
когда progressValue
изменения.
Однако я по-прежнему испытываю проблемы с анимацией:
__block NSDate *date = [NSDate date];
[UIView animateWithDuration:3
animations:^{
self.progressView.progressValue = 1.f;
}
completion:^(BOOL finished1) {
NSLog(@"first animation completed in %f", [[NSDate date] timeIntervalSinceDate:date]);
date = [NSDate date];
[UIView animateWithDuration:3
animations:^{
self.progressView.progressValue = 0.f;
}
completion:^(BOOL finished2) {
NSLog(@"second animation completed in %f", [[NSDate date] timeIntervalSinceDate:date]);
[self animateProgress];
}];
}];
Моим круговой обзор прогресс одушевляет progressValue
изменения и выполнение кода выше говорит, что каждая анимация занимает около 3 секунд. К сожалению, на экране вид анимации очень быстрый (анимация завершается в доли секунды).Вот как это выглядит:
Я не уверен, где проблема, но я заметил, что изменение в [CABasicAnimation animationWithKeyPath:@"strokeEnd"]
Ключевой путь от strokeEnd
к чему-то еще не дает никакого эффекта (анимация всегда выглядит одинаково).
Любые намеки на то, что мне не хватает здесь, будут оценены.
UPDATE 2
Я только заметил, что анимация на самом деле срабатывает этих двух линий в setProgressValue:
сеттере:
self.progressOvalLayer.strokeEnd = MIN(1, MAX(0, progressValue));
self.backgroundOvalLayer.strokeEnd = MIN(1, MAX(0, 1 - progressValue));
Это выглядит как моя реализация actionForLayer:forKey:
не работает вообще, несмотря на выполнение (проверено с помощью brakepoint).
Интересно, что я делаю неправильно?
ОБНОВЛЕНИЕ - РЕШЕНИЕ НАЙДЕНО
Это произошло, что я пытался оживить основной слой моего UIView
вместо пользовательских слоев, который содержит овальные формы. Мне нужно было исправить ошибку actionForLayer:(CALayer *)layer forKey:
, чтобы она работала (check out fixed source code). Это решает мою проблему.
Спасибо за подсказки, я обновил свою реализацию и вопрос. К сожалению, я все еще не умею правильно выполнять анимацию. Пожалуйста, ознакомьтесь с моим обновленным вопросом. – Darrarski