Оживить просмотр многократно и непрерывно

Я моделирую некоторые эффекты, такие как падающие листья, снег и дождь. Моим первым вызовом было использование 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, Это идеально подходит для повторения вещей! Единственная проблема, о которой я могу думать, это то, что преобразование и значения должны быть инкрементными...

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