How can I flip a CALayer with CATransform3D? - iphone

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.

Related

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

The best way to implement drawing features like Keynote

I'm trying to make a little iPad tool's for drawing simple geometrical objects (rect, rounded rect, ellipse, star, ...).
My goal is to make something very close to Keynote (drawing feature), i.e. let the user add a rect (for instance), resizing it and moving it. I want too the user can select many objects and move them together.
I've thought about at least 3 differents ways to do that :
Extends UIView for each object type, a class for Rect, another for Ellipse, ... With custom drawing method. Then add this view as subview of the global view.
Extends CALayer for each object type, a class for Rect, another for Ellipse, ... With custom drawing method. Then add this layer as sublayer of the global view layer's.
Extends NSObject for each object type, a class for Rect, another for Ellipse, ... With just a drawing method which will get as argument a CGContext and a Rect and draw directly the form in it. Those methods will be called by the drawing method of the global view.
I'm aware that the two first ways come with functions to detect touch on each object, to add easily shadows,... but I'm afraid that they are a little too heavy ? That's why I thought about the last way, which it seems to be straight forward.
Which way will be the more efficient ??? Or maybe I didn't thought another way ?
Any help will be appreciated ;-)
Thanks.
I'd use the UIKit classes to do your drawing, then profile and optimise your code from there.
Apple/iPad info: link text
My first feeling was to make the 3rd way, but to be convinced, just after I've posted my message, I did some tests with just a global view and over 200 geometrical forms (Rect, Rounded Rect and Ellipse) on it and I move only a half with touchMoved event. I did this test with the way 1 (Subclassing UIView) and the way 3 (Subclassing NSObject), the way 2 seems to me too restrictive and not help me at all.
The resuslt is that the way 1 seems to be more efficient... There is no lag when I move 60 objects together ! Moreover using this way would probably help me because using view comes which some interesting functions like touch detection on complex path (see UIBezierPath), object hierarchy handled by the UIView classe...
So I will use that way and come back here to share my results ;-)
Regards
It's better to use CGLayer objects. The benefits are:
It's much faster and more memory efficient. For simple objects, adding a view is much more expensive and complicates the view hierarchy. For complicated objects, the caching done on CGLayers can boost performance.
It's easy to group objects together. you just put everything in a new layer, and voila! There's almost no overhead.
Using CGLayer and other Quartz objects gives you a lot more flexibility.
The only drawback is that you have to directly use Quartz 2D. It's not really difficult, but needs some learning if you haven't used it before.
CAShapeLayer pretty much handles your option 2. It does rect and rounded rect (see cornerRadius) by default, or you can give it a path for any arbitrary shape. For your option 1, you can use a CAShapeLayer with a UIView instead of implementing drawRect and it may be faster.

Animate a GIF using Core Animation layers?

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

How do I create a custom page curl Core Animation?

I'm trying to create a "page curl" animation of an image in my iPhone application. I t UIViewAnimationTransitionCurlUp, and it's undocumented Core Animation siblings, however the image I need to animate is a transparent PNG, with "uneven" (some alpha pixels) outlines. When using the aforementioned pre-made transition, those alpha pixels are painted black as soon as the animation starts, which looks terribly ugly.
Therefore, I seek to create a Core Animation of my own. I have tried to research the subject, but have been unable to find a good overview of the techniques involved. The implementation would of course have to be more complex than a single property change, I get the feeling that even CATransform3D would be to limited for this purpose, as the image needs to have different 3D transformations applied in different parts of it - changing over time. How would one then go about this subject? I'm very grateful for any thoughts or ideas!
Best,
Eli
As Corey points out, you'll probably need to go with OpenGL ES for this one. Core Animation exposes the ability to work with layers, even in 3-D, but all layers are just rectangles and they are manipulated as such. You can animate the flipping of a layer about an axis, even with a perspective distortion, but the kind of curving you want to do is more complex than you can manage using the Core Animation APIs.
You might be able to split your image up into a mesh of tiny layers and manipulate each using a CATransform3D to create this curving effect, but at that point you might as well be using OpenGL ES to create the same effect.
The book Core Animation for Mac OS X and the iPhone: Creating Compelling Dynamic User Interfaces from Pragmatic Programmer may help you write custom Core Animation animations.

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.