Оживить просмотр многократно и непрерывно
Я моделирую некоторые эффекты, такие как падающие листья, снег и дождь. Моим первым вызовом было использование CAEmitterLayer, который работает очень хорошо, но мне нужно визуализировать слой в контексте, чтобы сохранить его как изображение, и это кажется невозможным или, по крайней мере, очень сложным.
Так что я работаю с некоторыми видами анимации. Мне нужно постоянно анимировать мои изображения, чтобы они могли проваливаться через экран и появляться поверх него, каждый с разной скоростью.
Так что я переместил каждое изображение на экран с animateWithDuration
и когда анимация завершена, я вызываю метод, который делает это рекурсивно, из блока завершения, чтобы изображение могло добраться до конца экрана. Как только imageView достигает конца экрана, я перемещаю его сверху.
Проблема в том, что когда анимация закончена, мой imageView немного останавливается, пока блок завершения не вызывает метод рекурсивно, я хочу, чтобы он был непрерывным.
Мой код генерирует случайную позицию для каждого imageView, и моя продолжительность анимации очень мала, поэтому я всегда могу обновить местоположение imageView в случае, если пользователь коснется кнопки, чтобы сохранить вид как изображение.
Во всяком случае, вот мой код:
- (void)effectOnObject:(UIImageView *)object{
NSInteger initialX;
NSInteger initialy;
CGFloat duration;
//the object have reached the end of screen
if (object.frame.origin.y >= self.frame.size.height) {
//generate random position to relocate the object on x axis
initialX = arc4random() % 321;
//generate random position to relocate the object on y axis (little bit above top of screen)
initialy = ((NSInteger)-object.frame.size.height) - arc4random() % 11;
//duration 0 so the object can be replaced without animation
duration = 0.0;
}
else{
initialX = object.frame.origin.x;
//this change the speed of object
initialy = object.frame.origin.y + 10
//setted duration to short time
duration = 0.01;
}
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
[object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
}
completion:^(BOOL completed){
//recursively call
[self effectOnObject:object];
}];
}
- (void)startEffect{
//initiate effect on each imageView
for (UIImageView *object in self.subviews) {
[self effectOnObject:object];
}
}
Как сделать эту анимацию многократно и непрерывно, без перерыва, когда метод вызывается рекурсивно из блока завершения и анимация перезапускается?
2 ответа
Вам не нужно делать анимацию с длительностью 0, когда объект достигает конца экрана. Просто проверьте это в своем блоке завершения и переместите представление перед рекурсивным вызовом. Кроме того, длительность 0,01 кажется немного экстремальной (100 кадров в секунду). Возможно, более разумное значение, такое как 0,1, поможет.
Что-то вроде этого:
- (void)effectOnObject:(UIImageView *)object{
//setted duration to short time
CGFloat duration = 0.1;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
NSInteger initialX = object.frame.origin.x;
//this change the speed of object
NSInteger initialy = object.frame.origin.y + 10;
[object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
}
completion:^(BOOL completed){
NSInteger initialX = arc4random() % 321;
//generate random position to relocate the object on y axis (little bit above top of screen)
NSInteger initialy = ((NSInteger)-object.frame.size.height) - arc4random() % 11;
[object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
//recursively call
[self effectOnObject:object];
}];
}
Из того, что я прочитал вкратце, вы должны проверить CAReplicatorLayer
, Это идеально подходит для повторения вещей! Единственная проблема, о которой я могу думать, это то, что преобразование и значения должны быть инкрементными...