I have a CALayer with 9 sublayers, which occasionally flip vertically and I use CATransform3D to do so. Now, my problem is that, sometimes, I need to apply a transformation to the super layer of those 9 layers. When I do that, the position and transformation of the sublayers gets all screwed up. Is there a way to ignore the transform of the parent layer, so that it doesn't affect the sublayers?
The whole point of the layer tree is to inherit attributes like transforms. If you don't want certain layers to inherit from their parent, insert them as another layer's children.
You could also apply the inverse transform to the child layers, but that would be hackish, compute-intensive, and open the door to rounding errors.
Related
How is a CALAyer.frame related to its UIView.frame? (in this case specifically a UIImageView.frame).
Given that the values for a CALayer.frame potentially differ from its UIView.frame following a CAtransform3D transformation, do they no longer have any connection? (and subsequently, should I be more concerned about managing the dimensions of my CALayer rather than my UIImageView in my superview?).
If you are working with Core Animation and layers, you should focus on the following CALayer properties:
position
bounds
anchorPoint
transform
A quote from Apple Technical Q&A QA1620 available here:
Q: When I try to animate the frame of a CALayer nothing happens. Why?
A: The frame property of a CALayer is a derived property, dependent on
the position, anchorPoint, bounds and transform of the layer. Instead
of animating the frame, you should instead animate the position or
bounds, depending on what effect you are trying to accomplish.
For an assignment I was told to experiment with the Unity hierarchy by making an amusement ride. I created a surface that moves up and down that works fine. When I add new objects to the surface that moves up and down and attempt to rotate them they also scale at the same time. I'm not sure why this happens. I have tried making them outside of the root object then adding them in but it does the same thing. If someone could give me a hint as to what I'm doing wrong that would be awesome.
If they scale right in the moment when you add them to the surface, then you probably scaled the surface before. In an object hierarchy all objects inherit the transformations of their parents.
You can avoid that by creating your tree with empty objects and only attach the visible objects as leafs.
Instead of doing it this way (which will result in the sub-objects beeing scaled according to the scale of the surface):
Surface
+SubObject 1
+SubObject 2
You can do it that way:
EmptyObject (scale 1)
+Surface
+SubObject 1
+SubObject 2
That should solve your problem
Pretty naive question. I don't really understand the term 'translate' here.
While both are functions that modify a CATransform3D, the modification they perform is different. CATransform3DTranslate moves transforms the coordinate space by moving it in the x,y,z space. If you apply a CATransform3DTranslate to an object's transform (e.g a CALayer) it would change position in the screen. CATransform3DScale will resize the space, making transformed objects bigger and smaller. If you apply a CATransform3DScale to an object's transform is would change size.
Do I have to move the layer frame or apply translate matrix transformation to layer? Or perhaps I can move the contents inside of the layer? If contents is not movable inside of layer, how it would position initially?
A CALayer has a frame (or, equivalently, a bounds and an origin), which is used logically to determine what to draw. When drawInContext: or equivalent is called, it's the frame that determines how the contents are produced.
However, like OS X, iOS adopts a compositing window manager, which means that views know how to draw their output to a buffer and the buffers are combined to create the view, with the window manager figuring out what to do about caching and video memory management in between.
If you adjust the transform property of the view or of the layer class, then you adjust how the compositing happens. However, the results of drawInContext: should explicitly still be the same so the window manager knows it can just use the cached image.
So, for example, if you set a frame of size 128x128 and then a transform that scales the CALayer up to double, you'll occupy a 256x256 area of the screen but the image used for compositing will be only 128x128 in size, making each source pixel into four target pixels. If you set a frame of size 256x256 and the identity transform, you'll cover the same amount of screen space but with each source pixel being 1:1 related to a target pixel.
A side effect is that changing the frame causes a redraw from first principles. Changing the transform doesn't. So the latter is usually faster, and is also the thing to do if you decide to use something like CATiledLayer (as used in Safari, Maps, etc) that draws in a separate thread and may take a while to come up with results.
As a rule of thumb, you use the frame to set the initial position and update the frame for normal work stuff. You play with the transform for transitions and other special effects. However, all of the frame and transform properties of a CATiledLayer are animatable in the CoreAnimation sense, so that's really still at your discretion.
Most people don't work on the level of a CALayer, but prefer to work with UIViews. In which case the comments are mostly the same, with the caveat that you can then adjust the [2d] transform on the view or the [3d] transform on the view's layer and have the compositor figure it all out, but change the frame to prompt a redraw.
Greetings... I come in peace, shoot to kill...
I have a container of type UIView (A Grid) and add many sublayers to the layer of the UIView (CALayers representing cells within the grid).
Within the Cell, I render many UIImages at different locations using CGContextDrawImage. I am well aware of the need to Translate and Scale, but the scaling (flipping) is with reference to the superviews (Grid) co-ordiantes and the origin of the Cell CALayer is not (0,0).
Therefore my rendering is all over the shop (mostly off screen). What is the best way to handle the translating and scaling when the UIImage is not at (0,0). Is there an established design pattern I should be using.
I solved this issue by just manually offsetting the translation by double the y origin.