{"id":67,"date":"2011-02-13T15:16:58","date_gmt":"2011-02-13T21:16:58","guid":{"rendered":"https:\/\/www.flom.com\/?p=67"},"modified":"2025-11-04T15:12:46","modified_gmt":"2025-11-04T21:12:46","slug":"ipad-uiimageview-image-based-animation-alternative","status":"publish","type":"post","link":"https:\/\/www.flom.com\/?p=67","title":{"rendered":"iPad UIImageView image-based animation alternative"},"content":{"rendered":"<p>I&#8217;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&#8217;s <a href=\"http:\/\/www.modejong.com\/iPhone\/\">PNGAnimatorDemo<\/a>, which completely solved the memory limit problem.<\/p>\n<p>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.<\/p>\n<p>The first thing to be done was to create a new property &#8216;viewCGRect&#8217; 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.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">- (void)loadView { \r\n\/\/ UIView *myView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; \r\nUIView *myView = [[UIView alloc] initWithFrame:viewCGRect]; \r\nmyView autorelease]; \r\nself.view = myView; \r\n\r\n\/\/ FIXME: Additional Supported Orientations \r\nif (animationOrientation == UIImageOrientationUp) { \r\n    \/\/ No-op \r\n} else if (animationOrientation == UIImageOrientationLeft) { \r\n    \/\/ 90 deg CCW [self rotateToLandscape]; \r\n} else if (animationOrientation == UIImageOrientationRight) { \r\n    \/\/ 90 deg CW [self rotateToLandscapeRight]; \r\n} else { \r\n    NSAssert(FALSE,@\"Unsupported animationOrientation\"); \r\n}<\/pre>\n<p>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.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">- (void) startAnimator:(NSString *) pref endingWith: (int) end andFrame:(CGRect) rect { \r\n\/\/[viewController.view removeFromSuperview]; \r\n\r\nself.animatorViewController = [ImageAnimatorViewController imageAnimatorViewController]; \r\n\r\nNSArray *names = [ImageAnimatorViewController arrayWithNumberedNames:pref \r\nrangeStart:1 \r\nrangeEnd:end \r\nsuffixFormat:@\"%02i.png\"]; \r\n\r\nNSArray *URLs = [ImageAnimatorViewController arrayWithResourcePrefixedURLs:names]; \r\n\r\n\/\/ setting the public property for our custom CGRect: \r\n\r\nanimatorViewController.viewCGRect = rect; \r\n\r\n\/\/ we no longer need to provide an orientation \/\/animatorViewController.animationOrientation = UIImageOrientationUp; \/\/ Rotate 90 deg CCW \r\nanimatorViewController.animationFrameDuration = ImageAnimator15FPS; \r\nanimatorViewController.animationURLs = URLs; \r\nanimatorViewController.animationRepeatCount = 0; \r\n\r\n\/\/ Show animator before starting animation \r\n\r\n\/\/ add the animatorViewController.view as a subView: \r\n[self.view addSubview:animatorViewController.view]; \r\n\r\n[[NSNotificationCenter defaultCenter] addObserver:self \r\nselector:@selector(animationDidStartNotification:) \r\nname:ImageAnimatorDidStartNotification \r\nobject:animatorViewController]; \r\n\r\n[[NSNotificationCenter defaultCenter] addObserver:self \r\nselector:@selector(animationDidStopNotification:) \r\nname:ImageAnimatorDidStopNotification \r\nobject:animatorViewController]; \r\n\r\n[animatorViewController startAnimating]; }<\/pre>\n<pre class=\"lang:objc decode:true \" title=\"second chunk\">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. \r\n\r\n<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">- (void) stopAnimator { \r\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:ImageAnimatorDidStartNotification object:animatorViewController]; \r\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:ImageAnimatorDidStopNotification object:animatorViewController]; \r\n    [animatorViewController stopAnimating]; \r\n    [animatorViewController.view removeFromSuperview]; \r\n    self.animatorViewController = nil; \r\n} \r\n\r\n- (void) clearAnimation { \r\n    [animatorViewController.view removeFromSuperview]; self.animatorViewController = nil; \r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been troubleshooting a project that animates 24 different sets of png images. Each set containing around 30 images. The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":504,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[9,7,8,10],"tags":[],"class_list":["post-67","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ios","category-ipad","category-iphone","category-objective-c"],"uagb_featured_image_src":{"full":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869.png",1024,1024,false],"thumbnail":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869-150x150.png",150,150,true],"medium":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869-300x300.png",300,300,true],"medium_large":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869-768x768.png",768,768,true],"large":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869.png",1024,1024,false],"1536x1536":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869.png",1024,1024,false],"2048x2048":["https:\/\/www.flom.com\/wp-content\/uploads\/2011\/02\/image-9a796122-8f06-4eb5-8ee8-9b44cc89c869.png",1024,1024,false]},"uagb_author_info":{"display_name":"Todd Flom","author_link":"https:\/\/www.flom.com\/?author=1"},"uagb_comment_info":0,"uagb_excerpt":"I&#8217;ve been troubleshooting a project that animates 24 different sets of png images. Each set containing around 30 images. The [&hellip;]","_links":{"self":[{"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/posts\/67","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.flom.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=67"}],"version-history":[{"count":14,"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/posts\/67\/revisions"}],"predecessor-version":[{"id":189,"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/posts\/67\/revisions\/189"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.flom.com\/index.php?rest_route=\/wp\/v2\/media\/504"}],"wp:attachment":[{"href":"https:\/\/www.flom.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=67"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.flom.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=67"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.flom.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=67"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}