Reputation: 535
I have an animation of a menu background that is 21 frames. I load them into memory using the below code in the view's viewDidLoad method.
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;
Unfortunately, doing [settingsBackground startAnimating]; doesn't work in the viewDidLoad method. Is there some way to preload the animation so there isn't a 1-3 second delay on first run?
Upvotes: 2
Views: 3344
Reputation: 4425
The problem with each of these answers is that the suggested "fix" is to preload all your image data into memory. That can and will result in crashes if your images are too big or there are too many images, see my answer for uiimage-animation-causing-app-to-crash-memory-leaks for more detailed info. The real fix is that you need to decompress the images but not hold them all in memory. Or, you can use a movie format that already does the decompression for all frames in one step, so that changing from frame to frame is not a costly operation.
Upvotes: 2
Reputation: 1256
I wouldn't normally recommend using imageNamed and relying on the in-built caching mechanisms. You'll find a lot of discussion on this if you search, but also it won't necessarily pre-render your images anyway.
I use the following code to pre-load and pre-render images so there is no delay when animating the first time through.
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;
Upvotes: 10
Reputation: 1514
Try the following code, normally you should have no delays. Also this code is simpler :
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];
Upvotes: -1
Reputation: 4561
The animationImages
property of UIImageView requires an array of UIImage
objects, not an array of NSData objects.
You may also want to set the duration and repeatCount, even though they have default values.
Example:
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];
Upvotes: 0