如何为给定的对象数组同时运行多个UIAnimation块?

时间:2015-01-19 11:38:34

标签: objective-c uiimageview core-animation uianimation

我需要在屏幕上移动5个图像并执行过渡效果,例如旋转 - >旋转动画完成时:移动(移动完成时:然后重复处理)

我可以获得1张图片来完成这项工作,但效果很好。

我遇到的问题是我需要为5张图片做这件事;要求是所有图像(或imageViews)都需要动画同时运行。

我使用一个自定义对象,里面有一个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. 循环浏览我的5张图片
  2. 执行我的旋转 - >移动 - >在每个图像上重复(永久)动画
  3. 但我不确定如何使其适用于存储在数组中的多个uiimageviews

    有办法做到这一点吗?

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题,下面的代码应该做你想要的。它旨在按以下顺序执行以下操作:

  1. 同时以相同的持续时间将视图/飞机/无论数组中的所有项目旋转到新的旋转位置。
  2. 将视图/飞机/任何数组中的所有项目同时转换到新位置并持续相同的时间。
  3. 在#2结束时,重复,从#1开始。
  4. 现在,对于我的代码,我创建了VICAirplane作为UIView的简单子类,它具有单个属性: @property (assign,nonatomic) CGPoint rotateToLocation

    基本上,您尝试使用单个for循环来迭代对象,但如果在每个动画期间迭代数组,它会更好。你可以用我在下面显示的方式链接它们,但是你也可以为动画链的每个“链接”创建单独的方法,然后在每个方法上迭代一次数组。在任何一种情况下,您都需要在动画块中迭代数组 in / during ,而不是在它之外。当你在它之外迭代时(正如你的代码在上面做的那样),你正在为每个对象创建一个单独的动画块,所有这些都将被独立处理。

    无论如何,下面的代码创建了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
    

答案 1 :(得分:0)

我只是把我的循环放在我的应用程序的不同部分,现在它的效果要好得多。

最初我这样做了:

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

我不需要将for循环放在我的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];
                                                      }
                                                  }
                                              }];
                         }
                     }];

}