2015-01-19 2 views
1

Мне нужно перемещать 5 изображений по экрану и выполнять переходные эффекты, такие как поворот -> при завершении анимации анимации: move (при завершении перемещения: затем повторить процесс)Как запустить несколько блоков UIAnimation в одно и то же время для заданного массива объектов?

Я могу получить 1 изображение для этого, это работает отлично.

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

Я использую пользовательский объект, который имеет UIImageView внутри него

-(void)stopRepeatingAnimationForView:(UIView *)view 
{ 
    self.enableRepeatingAnimation = NO; 
    [view.layer removeAllAnimations]; 
} 

- (void)startRepeatingAnimationForView:(UIView *)view 
{ 
    self.enableRepeatingAnimation = YES; 
    [self repeatingAnimationForView:view]; 
} 

- (void)repeatingAnimationForView:(UIView *)view 
{ 
    //VICAirplane *planeObj = [self.airplanes objectAtIndex:0]; 
    for (VICAirplane *planeObj in self.airplanes) { 


      [UIView animateWithDuration:3 
            delay:1 
           options:UIViewAnimationOptionCurveLinear 
          animations:^{ 
           planeObj.imageView.transform = CGAffineTransformRotate(planeObj.imageView.transform, planeObj.angleToRotate); 
          } completion:^(BOOL finished) { 

           if (finished==YES) { 
            [UIView animateWithDuration:5 
                  delay:0.0 
                 options:UIViewAnimationOptionCurveLinear 
                 animations:^{ 

                  planeObj.imageView.center = planeObj.rotateToLocation; 

                 } completion:^(BOOL finished) { 
                  if (finished==YES) { 
                   if (self.enableRepeatingAnimation) 
                   { 
                    CGPoint rotateToLocation = [self generateRandomLocation]; 
                    planeObj.rotateToLocation = rotateToLocation; 

                    [self performSelector:@selector(repeatingAnimationForView:) withObject:view afterDelay:0]; 
                   } 
                  } 
                 }]; 
           } 
          }]; 

    } // next 


} 

Если удалить петлю через массив или просто сделать его 1 массив длиной анимация работает отлично.

Но если я добавляю несколько анимаций, то все равно, и они начинают терять законченное состояние и в конечном итоге делают много беспорядков.

То, что я хотел бы сделать, это:

  1. Loop через мои 5 изображений
  2. Выполните мою Rotate -> шаг -> повтор (навсегда) анимация на каждом изображении

Но Я не уверен, как заставить его работать для нескольких uiimageviews, хранящихся в массиве

Есть ли способ сделать это?

ответ

0

Если я правильно понимаю ваш вопрос, следующий код должен делать то, что вы хотите. Он предназначен, чтобы сделать следующие вещи, в следующем порядке:

  1. Rotate всех элементов в представлении/самолете/независимо массив их новые повороты в то же время и за тот же период.
  2. Перевести все элементов в представлении/самолете/любом массиве в их новые местоположения одновременно и в течение одной и той же продолжительности.
  3. В конце # 2 повторите, начиная с # 1.

Теперь, для моего кода, я создал VICAirplane как простой подкласс UIView, который имеет одно свойство: @property (assign,nonatomic) CGPoint rotateToLocation.

В принципе, вы пытались создать одиночный цикл for, чтобы перебирать ваши объекты, но он будет работать лучше, если вы будете перебирать массив во время каждой анимации. Вы можете определенно связать их так, как я показываю ниже, но вы также можете создавать отдельные методы для каждой «ссылки» цепочки анимации, а затем перебирать массив по одному методу. В любом случае вам нужно перебрать массив в/во время блока анимации, а не за его пределами. Когда вы выполняете итерацию за пределами (как ваш код делает выше), вы создаете отдельный блок анимации для каждого объекта, все из которых будут обрабатываться независимо.

В любом случае, код ниже создает 5 цветных квадратов, которые вращаются, а затем переводится случайным образом в непрерывном цикле анимации.

// VICAirplane.h 
#import <UIKit/UIKit.h> 
@interface VICAirplane : UIView 
@property (assign, nonatomic) CGPoint rotateToLocation; 
@end 
// VICAirplane.m 
#import "VICAirplane.h" 
@implementation VICAirplane 
@end 

// ViewController.h 
#import <UIKit/UIKit.h> 
@interface ViewController : UIViewController 
@end 
// ViewController.m 
#import "ViewController.h" 
#import "VICAirplane.h" 
@interface ViewController() { 

} 
@property (strong, nonatomic) NSMutableArray *views; 
@property (assign, nonatomic) BOOL enableRepeatingAnimation; 
@end 
@implementation ViewController 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self setupUserInterface]; 
} 
- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    [self startRepeatingAnimation]; 
} 
- (void)setupUserInterface { 
    self.views = [NSMutableArray array]; 
    for (int i = 0; i < 5; i = i + 1) { 
     VICAirplane *newView = [[VICAirplane alloc] initWithFrame:CGRectMake((i * 100) + 20, (i * 100) + 20, 80, 80)]; 
     switch (i % 4) { 
      case 0: 
       newView.backgroundColor = [UIColor blueColor]; 
       break; 
      case 1: 
       newView.backgroundColor = [UIColor redColor]; 
       break; 
      case 2: 
       newView.backgroundColor = [UIColor greenColor]; 
       break; 
      case 3: 
       newView.backgroundColor = [UIColor brownColor]; 
       break; 
      case 4: 
       newView.backgroundColor = [UIColor purpleColor]; 
       break; 
      default: 
       break; 
     } 
     [self.views addObject:newView]; 
     [self.view addSubview:newView]; 
    } 
} 
- (CGPoint)generateRandomLocation { 
    CGFloat x = (CGFloat)arc4random_uniform(600); 
    CGFloat y = (CGFloat)arc4random_uniform(600); 
    return CGPointMake(x, y); 
} 
-(void)stopRepeatingAnimation { 
    self.enableRepeatingAnimation = NO; 
    [self.view.layer removeAllAnimations]; 
} 
- (void)startRepeatingAnimation { 
    self.enableRepeatingAnimation = YES; 
    for (VICAirplane *subview in self.views) { 
     subview.rotateToLocation = [self generateRandomLocation]; 
    } 
    [self repeatingAnimation]; 
} 
- (void)repeatingAnimation { 
    [UIView animateWithDuration:3 
          delay:1 
         options:UIViewAnimationOptionCurveLinear 
        animations:^{ 
         for (UIView *subview in self.views) { 
          // Just a random rotation between -2π and 2π 
          CGFloat rotationAngle = (arc4random_uniform(400 * M_PI) - (200 * M_PI))/100; 
          subview.transform = CGAffineTransformRotate(subview.transform, rotationAngle); 
         } 
        } 
        completion:^(BOOL finished) { 
         if (finished==YES) { 
          [UIView animateWithDuration:5 
                delay:0.0 
               options:UIViewAnimationOptionCurveLinear 
               animations:^{ 
                for (VICAirplane *subview in self.views) { 
                 subview.center = subview.rotateToLocation; 
                } 
               } 
               completion:^(BOOL finished) { 
                if (finished==YES) { 
                 if (self.enableRepeatingAnimation) { 
                  for (VICAirplane *subview in self.views) { 
                   subview.rotateToLocation = [self generateRandomLocation]; 
                  } 
                  [self performSelector:@selector(repeatingAnimation) withObject:nil afterDelay:0.0f]; 
                 } 
                } 
               } 
           ]; 
         } 
        } 
    ]; 
} 
@end 
+0

Из-за низкой репутации нельзя возвысить. Но большое спасибо! –

+0

Рад помочь! <15 chars> – mbm29414

0

Я просто поместил свою петлю в другую часть моего приложения, и теперь она работает намного лучше.

Первоначально я делал это:

- (void)repeatingAnimationForView:(UIView *)view 
{ 
    for (VICAirplane *planeObj in self.airplanes) { 
    } 
} 

мне не нужно ставить для цикла в моем startRepeatingAnimationForView методе и просто передаются Params к тому же методу

Вместо этого я должен был поставить его здесь (который я сейчас сделал и работает намного лучше, чем мой оригинал)

-(void)stopRepeatingAnimationForView:(UIView *)view 
{ 
    self.enableRepeatingAnimation = NO; 
    [view.layer removeAllAnimations]; 
} 

- (void)startRepeatingAnimationForView:(UIView *)view 
{ 
    self.enableRepeatingAnimation = YES; 
    for (VICAirplane *planeObj in self.airplanes) { 
     [self repeatAnimationWithParams:@{@"view":view, @"planeObj": planeObj}]; 
    } 
} 

-(void) repeatAnimationWithParams:(NSDictionary *)params 
{ 
    VICAirplane *planeObj = params[@"planeObj"]; 

    [UIView animateWithDuration:2 
          delay:1 
         options:UIViewAnimationOptionCurveLinear 
        animations:^{ 
         planeObj.imageView.transform = CGAffineTransformRotate(planeObj.imageView.transform, planeObj.angleToRotate); 
        } completion:^(BOOL finished) { 

         if (finished==YES) { 
          [UIView animateWithDuration:5 
                delay:0.0 
               options:UIViewAnimationOptionCurveLinear 
               animations:^{ 

                planeObj.imageView.center = planeObj.rotateToLocation; 

               } completion:^(BOOL finished) { 
                if (finished==YES) { 
                 if (self.enableRepeatingAnimation) 
                 { 
                  CGPoint rotateToLocation = [self generateRandomLocation]; 
                  planeObj.rotateToLocation = rotateToLocation; 

                  [self performSelector:@selector(repeatAnimationWithParams:) 
                    withObject:params 
                    afterDelay:0]; 
                 } 
                } 
               }]; 
         } 
        }]; 

} 
+0

Вы по-прежнему создаете множество разных, не связанных между собой блоков анимации (1 на объект/представление). Если что-то пойдет не так (маловероятно, но возможно), ваши анимации могут выйти из строя. Я бы порекомендовал их в очереди, как в моем примере кода. – mbm29414

+0

Хорошо, я сделаю это. Большое спасибо! –