在执行startAnimating时UIImageView动画延迟

时间:2011-10-22 22:32:32

标签: iphone objective-c ios ipad uiimageview

我有一个21帧的菜单背景动画。我使用视图的viewDidLoad方法中的以下代码将它们加载到内存中。

NSMutableArray *menuanimationImages = [[NSMutableArray alloc] init];

for( int aniCount = 0; aniCount < 21; aniCount++ )
{

    NSString *fileLocation = [[NSBundle mainBundle] pathForResource: [NSString stringWithFormat: @"bg%i", aniCount + 1] ofType: @"png"];
    NSData *imageData = [NSData dataWithContentsOfFile: fileLocation];

    [menuanimationImages addObject: [UIImage imageWithData:imageData]];

}

settingsBackground.animationImages = menuanimationImages;

不幸的是,做[settingsBackground startAnimating];在viewDidLoad方法中不起作用。有没有办法预加载动画,所以第一次运行时没有1-3秒的延迟?

4 个答案:

答案 0 :(得分:9)

我通常不推荐使用imageNamed并依赖于内置的缓存机制。如果你搜索,你会发现很多关于这个问题的讨论,但它也不一定会预渲染你的图像。

我使用以下代码预加载和预渲染图像,以便在第一次动画时没有延迟。

NSMutableArray *menuanimationImages = [[NSMutableArray alloc] init];

for (int aniCount = 1; aniCount < 21; aniCount++) {
    NSString *fileLocation = [[NSBundle mainBundle] pathForResource: [NSString stringWithFormat: @"bg%i", aniCount + 1] ofType: @"png"];
    // here is the code to pre-render the image
    UIImage *frameImage = [UIImage imageWithContentsOfFile: fileLocation];
    UIGraphicsBeginImageContext(frameImage.size);
    CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
    [frameImage drawInRect:rect];
    UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [menuanimationImages addObject:renderedImage];
}

settingsBackground.animationImages = menuanimationImages;

答案 1 :(得分:2)

每个答案的问题在于建议的&#34;修复&#34;是将所有图像数据预加载到内存中。如果您的图片太大或图片太多,可能会导致崩溃,请参阅我对uiimage-animation-causing-app-to-crash-memory-leaks的回答以获取更详细的信息。真正的解决方法是你需要解压缩图像,但不能将它们全部保存在内存中。或者,您可以使用已经在一个步骤中对所有帧进行解压缩的电影格式,以便逐帧更改并不是一项代价高昂的操作。

答案 2 :(得分:0)

UIImageView的animationImages属性需要一个UIImage个对象数组,而不是NSData对象数组。

您可能还想设置持续时间和repeatCount,即使它们具有默认值。

示例:

if (!self.idleView.animationImages) {
    self.idleView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"idle1.png"],
                      [UIImage imageNamed:@"idle2.png"],
                      [UIImage imageNamed:@"idle3.png"],
                      [UIImage imageNamed:@"idle4.png"],
                      [UIImage imageNamed:@"idle5.png"],
                      [UIImage imageNamed:@"idle6.png"],
                      [UIImage imageNamed:@"idle7.png"],
                      [UIImage imageNamed:@"idle8.png"],
                      [UIImage imageNamed:@"idle9.png"],
                      [UIImage imageNamed:@"idle10.png"],
                      [UIImage imageNamed:@"idle11.png"],
                      [UIImage imageNamed:@"idle12.png"],
                      [UIImage imageNamed:@"idle13.png"],
                      [UIImage imageNamed:@"idle14.png"],
                      [UIImage imageNamed:@"idle15.png"],
                      [UIImage imageNamed:@"idle16.png"],
                      [UIImage imageNamed:@"idle17.png"],
                      [UIImage imageNamed:@"idle18.png"],
                      [UIImage imageNamed:@"idle19.png"],
                      [UIImage imageNamed:@"idle20.png"]                
                      , nil];
    }
    self.idleView.animationRepeatCount = 0;
    self.idleView.animationDuration = 2.0;
    [self.view addSubview:self.idleView];
    [self.view sendSubviewToBack:self.idleView];
    [self.idleView startAnimating];

答案 3 :(得分:-1)

尝试以下代码,通常您应该没有延迟。此代码也更简单:

 NSMutableArray *menuanimationImages = [[NSMutableArray alloc] initWithCapacity:21];
 NSString *imageName;

 for( int aniCount = 1; aniCount < 21; aniCount++ )
 {
     imageName = [NSString stringWithFormat:@"bg%d.png", aniCount];
     [menuanimationImages addObject:[UIImage imageNamed:imageName]];
 }

 settingsBackground.animationImages = menuanimationImages;
 // all frames will execute in 2 seconds
 settingsBackground.animationDuration = 2.0;
 // repeat the annimation forever
 settingsBackground.animationRepeatCount = 0;
 // start animating
 [settingsBackground startAnimating];