UIView animateWithDuration и UIProgressView setProgress
Я хочу оживить мою прогрессию UIProgressView
от 0 до 1 в течение 10 секунд.
код:
[UIView animateWithDuration:10.0 animations:^{
[_myProgressView setProgress:1 animated:YES];
} completion:(BOOL finished)^{
if (finished) NSLog(@"animation finished);
}];
Анимация работает отлично, за исключением того, что завершение и NSLog
всегда вызываются мгновенно.
Я пробовал animateWithDuration: withDelay:
, но задержка не соблюдалась и выполнялась немедленно.
Кто-нибудь сталкивался с той же проблемой?
Спасибо за помощь.
Ответы
Ответ 1
Это старая проблема, но я все еще размещаю решение здесь. Решение оказалось очень простым.
Все, что вам нужно сделать, это:
[_myProgressView setProgress:1];
[UIView animateWithDuration:10.0 animations:^{
[_myProgressView layoutIfNeeded];
} completion:^(BOOL finished){
if (finished) NSLog(@"animation finished");
}];
Вот хорошее объяснение того, почему вы неправильно работали для вас:
http://blog.spacemanlabs.com/2012/08/premature-completion-an-embarrassing-problem/
Таким образом, вы не можете использовать метод setProgress:animated:
для анимации представления прогресса и получения желаемого поведения блока completion
. Однако просто установка progress
внутри блока не будет анимировать его, так как progress
не является анимирующим свойством.
Обратитесь к документации Apple, в которой говорится, что необходимо, чтобы свойство было анимированным:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/clm/UIView/animateWithDuration:animations:
Итак, вы просто обновляете значение свойства progress
вне блока анимации и делаете макет представления внутри блока анимации.
Ответ 2
Сделайте это простым, используя NSTimer, например,
[progressview setProgress:0 animated:NO];
NSTimer *t=[NSTimer scheduledTimerWithTimeInterval: 1.0f
target: self
selector: @selector(progressupdate)
userInfo: nil
repeats: YES];
Ниже приведена функция, которая обновляет ход выполнения,
-(void)progressupdate{
if(progressview.progress<1){
[progressview setProgress:(progressview.progress+=0.2) animated:YES];
}
else{
[t invalidate];
}
}
Надеюсь, это поможет....
Ответ 3
Это старый вопрос, но у меня была аналогичная проблема, и вот мое решение (извините, это в Swift). Часть завершения вызывается, когда анимация заканчивается. Он находится внутри настраиваемого класса UIProgressView.
override func setProgress(progress: Float, animated: Bool) {
self.progress = progress
if animated {
let duration: NSTimeInterval = 10.0
UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: {
self.layoutIfNeeded()
}, completion: { (completed) in
self.animationDuration = nil
})
} else {
self.layoutIfNeeded()
}
}
Ответ 4
То, что я узнал, - это набор анимаций UIview и анимации прогресса, которые работают намного приятнее и оживляют прогресс. Если вы просто используете комбинацию анимации и анимации progressview, она запускается напрямую, независимо от таймера анимации UIview.
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0f
target: self
selector: @selector(updateTimer)
userInfo: nil
repeats: YES];
}
- (void)updateTimer
{
if (progressView.progress >= 1.0) {
[timer invalidate];
}
[UIView animateWithDuration:1 animations:^{
float newProgress = [self.progressView progress] + 0.125;
[self.progressView setProgress:newProgress animated:YES];
}];
}
Не стесняйтесь настраивать время анимации еще лучше и плавно.