iPad UIImageView image-based animation alternative
I’ve been troubleshooting a project that animates 24 different sets of png images. Each set containing around 30 images. The App would eventually crash when run on an iPad after running through about half a dozen of the animations. Eventually running into a memory limit. In my search for solutions, I ran into Mo DeJong’s PNGAnimatorDemo, which completely solved the memory limit problem.
The example project he provides runs the animation full frame by default so I had to modify some things in order to add it as a subview to another view and to set it inside a CGRect.
The first thing to be done was to create a new property ‘viewCGRect’ with which I could set a CGRect for the ImageAnimatorViewController . I also took out the animationOrientation property and associated code since this is now being added as a subVIew to another view.
- (void)loadView { // UIView *myView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; UIView *myView = [[UIView alloc] initWithFrame:viewCGRect]; myView autorelease]; self.view = myView; // FIXME: Additional Supported Orientations if (animationOrientation == UIImageOrientationUp) { // No-op } else if (animationOrientation == UIImageOrientationLeft) { // 90 deg CCW [self rotateToLandscape]; } else if (animationOrientation == UIImageOrientationRight) { // 90 deg CW [self rotateToLandscapeRight]; } else { NSAssert(FALSE,@"Unsupported animationOrientation"); }
Then inside my superViewController I modified the startAnimator method in order to pass a different file name prefix for every animation. As well as a specific length (each animation had varying lengths) and a CGRect with which to draw the animation.
- (void) startAnimator:(NSString *) pref endingWith: (int) end andFrame:(CGRect) rect { //[viewController.view removeFromSuperview]; self.animatorViewController = [ImageAnimatorViewController imageAnimatorViewController]; NSArray *names = [ImageAnimatorViewController arrayWithNumberedNames:pref rangeStart:1 rangeEnd:end suffixFormat:@"%02i.png"]; NSArray *URLs = [ImageAnimatorViewController arrayWithResourcePrefixedURLs:names]; // setting the public property for our custom CGRect: animatorViewController.viewCGRect = rect; // we no longer need to provide an orientation //animatorViewController.animationOrientation = UIImageOrientationUp; // Rotate 90 deg CCW animatorViewController.animationFrameDuration = ImageAnimator15FPS; animatorViewController.animationURLs = URLs; animatorViewController.animationRepeatCount = 0; // Show animator before starting animation // add the animatorViewController.view as a subView: [self.view addSubview:animatorViewController.view]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(animationDidStartNotification:) name:ImageAnimatorDidStartNotification object:animatorViewController]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(animationDidStopNotification:) name:ImageAnimatorDidStopNotification object:animatorViewController]; [animatorViewController startAnimating]; }
Then lastly I commented out parts of the stopAnimator method so that the final frame of each animation would remain until I needed to dispose of it by using another method clearAnimation.
- (void) stopAnimator { [[NSNotificationCenter defaultCenter] removeObserver:self name:ImageAnimatorDidStartNotification object:animatorViewController]; [[NSNotificationCenter defaultCenter] removeObserver:self name:ImageAnimatorDidStopNotification object:animatorViewController]; [animatorViewController stopAnimating]; [animatorViewController.view removeFromSuperview]; self.animatorViewController = nil; } - (void) clearAnimation { [animatorViewController.view removeFromSuperview]; self.animatorViewController = nil; }