Animate a GIF using Core Animation layers? - iphone

I'm trying to animate a GIF and I hit a roadblock. I have an example of what I'm trying to do that uses the individual frames of the GIF and setting the animationImages property of a UIView. However in my project, the thing I want to animate is drawn using Layers. I'm looking for a quick and easy way to animate the frames without introducing too much complexity. Is there any animationImages equivalent with Layers? Does anybody have any ideas?

Another solution:
The contents property of a CALayer is animatable. Meaning you can create a CAKeyFrameAnimation and supply it with an array of images for each frame. You can also set the timing of it.
Note, will likely work better with PNGs
Maybe that helps instead.

Here you go, enjoy:
http://github.com/jamesu/glgif

Related

Subclassing an UIView efficiently

Guys I'm having some troubles subclassing an UIView.
I'm creating an IconView.
Simply it's a container for some other subviews.
In my IconView i have this iVar:
UIImageView _background
UIImageView _icon
UILabel _iconLabel.
When I initialize the IconView I setup this 3 iVar with images, text and some quartz effect like roundCorner and Shadow and then I add them to the self view.
Everything is Ok but if I insert some of this IconView (i.e. 10) inside an empty scrollview the scroll effect is not smooth. I tried before inserting thousand of simple UIViews in a scrollview and the scroll animation works perfectly.
With just 10 of my IconView the scroll animation works really bad.
I could approach differently retaining UIImages instead of UIImageViews and draw it inside drawRect: method but in this case I'm gonna loose Autoresizing property and Quartz effect.
Any suggests?
Thank, Gabriele.
Unfortunately, a UIScrollView gets slow pretty fast. There are a lots of posts and articles on this topic out there, like this Question and this (defect) blogpost along with it's sample code. There are also three sessions about 'Performance optimization in iOS' in the 2010's WWDC videos which I highly recommend to watch. To summarize the conclusions: Use as few subviews as you can and take special care of avoiding transparencies.
Ok, so much for the general 'Performance in ScrollViews' talk, now to your case: Having the same problem, I used all the tips from the articles and videos above and while they improved the performance, it just wasn't enough. I had, like you, used rounded corners one some images and I found out that this absolutely kills performance. Just deactivating them helped more than everything else. It's probably the same with the shadow effects.
Now, most likely, you want to keep those rounded corners. I would suggest that you create a copy of your images (or take the original, if possible) and than manipulate them directly, using those awesome classes. This way, the effects will only be applied once. It works perfectly for me. For you shadows, you can probably just create some in Photoshop and use them in a new ImageView.
If that isn't enough, you should try to cache your IconViews, like TableViewCells are cached, if you don't already do this.
The problem will probably be the Quartz shadows. They can really slow the rendering down if used a lot.
Before you write them off, you might try setting your CALayer's shouldRasterize property to YES. This makes quartz render the shadow only once and store it in a buffer. See how it goes.

What to use for animation for iPad? SVG? GIF? Other?

I am making an app for the iPad/iphone and I want to have a star that tinkles every now and then and/or a rocket that shoots up randomly . What would be the best way to do that? Someone told me to use SVG and another told me that GIFs would be just fine.
SVG isn't going to work unless you are displaying the content in a UIWebView, you can either build the views using drawing code and perform the animations with core animation or use images, the first being far more efficient. Check out Apple's Core Animation Guide for more information.
UIImageView has a property animationImages which can be an array of UIImages. That'll certainly be lighter than a web view!
UIView animations are pretty elegant, though if you're code-phobic they're probably not for you. Don't let the affine transformation stuff scare you, it's simpler than it looks.

How can I flip a CALayer with CATransform3D?

Looking for help on how to have a CALayer flip like a UIView using CATransform3D.
I have seen some articles but I'm having a hard time understanding the 4D and 3D coordinates system, model and references. I also read apple's documentation, but I'm not understanding it either.
My goal is to flip a card located within a layer within a view. I know I could use uiview to do the same thing, but i would rather use a calayer
Thanks in advance for your help.
Drew McCormack provides code for just such an animation here, based on previous work by Mike Lee. While he bases his flipping around an NSView, the actual animation is performed on a CALayer generated from the contents of the view. The few view-related components of his implementation can be replaced by pure layers in your case.

Access interim points while UIView is animated

I'm animating an image in an UIImageView. This works just great with Core Animation. Now I want to attach one end of a line permanentely to the center of this UIIMageView. But with Core Animation I only get the starting point and the end point of the UIImageView. Is there a possibility to access interim points during the animation? I want to extend the functionality to many UIImageViews, which are animated, with a line attached to them. I don't want to create timers to monitor all animations and calculate my own interim points. Does somebody have any suggestions? Thanks!
Bye, Björn
If you're using Core Animation (I'm not sure if this works with strictly UIView-based animation), you should be able to get a particular instantaneous value of your property by looking at the presentationLayer property of your view's backing CALayer. That property exposes a read-only copy of the current set of values as a layer is animating. You can look at this on a display link "timer" and update something else, etc.
I'm having a tough time picturing exactly what you're trying to accomplish overall, but this might get you started.
I found this post, which points to the right direction: http://dbachrach.com/blog/2008/04/instantaneous-frame-of-moving-core-animation-views/
But there's still one problem: this seems to work for CABasicAnimations only, not for the standard animations. Is there a way to access interim points when using standard animations ([UIView beginAnimation] ...)?? Thanks.
Björn

How do I use CALayer with the iPhone?

Currently, I have a UIView subclass that "stamps" a single 2px by 2px CGLayerRef across the screen, up to 160 x 240 times.
I currently animate this by moving the UIView "up" the screen 2 pixels (actually, a UIImageView) and then drawing the next "row".
Would using multiple CALayer layers speed up performance of rendering this animation?
Are there tutorials, sample applications or code snippets for use of CALayer with the iPhone SDK?
The reason I ask is that most of the code snippets I find that demonstrate simple examples of CALayer employ method calls that do not work with the iPhone SDK. I appreciate any advice or pointers.
Okay, well, if you want something that has some good examples of CA good that draws things like that and works on the phone, I recommend the GeekGameBoard code that Jens Aflke published (it is an improved version of some Apple demo code).
Based on what you are describing I think you are doing somthing way more complicated than it needs be. My impression is you want basically a static view that you are animating by shifting its position so that it is partially off screen. If you just need to set some static content in your drawRect going through layers is not going to be faster than just calling CGFillRect() with your color. After that you could just use implicit animations and the animator proxy on UIView to move the view. I suspect you could even get rid of the custom drawRect: implementation with a patterned UIColor, but I honestly have not benchmarked the difference between the two.
What CALayer methods are you seeing that don't work on iPhone? Aside from animation features tied to CoreImage I have not noticed much that is missing. The big thing you are likely to notice is that all views are layer backed (so you do not need to do anything special to use layers, you can just grab a UIView's layer through the layer accessors methos), and the coordinate system has a top left origin.
In any event, generally having more things is slower than having fewer things. If you are just repeating the same pattern over and over again you are likely to find the best performance is implementing a custom UIView/CALayer/UIColor that knows how to draw what you want, rather than placing visually identical layers or views next to each other.
Having said that, generally layers are lighter weight than views, so if you have a lot of separate elements that you need to keep logically separated you will find that moving to layers can be a win over using views.
You might want to look at -[UIColor initWithPatternImage:] depending on exactly what you are trying to do. If you are using this two pixel pattern as a background color you could just make a UIColor that draws it and set the background.
What CALayer methods are you seeing that don't work on iPhone?
As one example, I tried implementing the grid demo here, without much luck. It looks like CAConstraintLayoutManager and CAConstraint are not available in QuartzCore.h.
In another attempt, I tried a very simple, small 20x20 CALayer object as a sublayer of my UIView's layer property, but that didn't show up.
Right now, I have a custom UIView of which I override the drawRect method. In drawRect I grab a context and render two types of CGLayerRefs:
At "off" cells I draw the background color across the entire 320x480 canvas.
At "on" cells, I either draw a single CGLayerRef across a grid of 320x480 pixels (initialization) or across a 320x2 row (animation).
During animation, I make a UIImageView clip view from 320x478 pixels, and draw a single row. This "pushes" my bitmap up the screen two pixels at a time.
Basically, I'd like to test whether or not using CALayer will accomplish two things:
Make my rendering faster, if CALayer has less overhead than what I'm doing now
Make my animation smoother, by letting me transition a layer up the screen smoothly
Unfortunately, I can't seem to get a basic CALayer working at the moment, and haven't found a good chunk of sample code to look at and play with.