During an animation, can the properties of every CALayer be read atomically in the presentationLayer tree? - core-animation

I'm looking for a solution to make a video from a CoreAnimation animation.
If I recursively enumerate the sublayers of my root CALayer presentation layer, is there a risk that the values(position, transform, opacity..) keep on changing while I'm a reading the properties in the (presentation) tree ? Or is the presentation layer like a deep copy of the CALayer hierarchy ?

The presentation layer is a deep copy of the model layer, with all the active animations applied. It's not actually the literal presentation tree that's used to render to screen, it's just an approximation.

Related

NSVisualEffectView with mask has jagged corners

In one of the WWDC 2014 talks on the new Yosemite UI, it says to avoid the use of NSVisualEffectView in masked layers. Unfortunately my view's layer does have a shape mask, and as a result the visual effect view in it has an ugly jagged edge effect:
However I know it must be somehow possible to create a masked visual effect view, partly due to 2 reasons:
The image mask property on NSVisualEffectView produces a smooth, anti-alised mask (but requires an unmasked background behind it, and not just an unmasked parent view)
NSPopover and NSMenu seem to be able to achieve a smooth mask that changes with dimensions:
Although it is doubtable as to wether or not they use NSVisualEffectView, and not a custom blurred view.
Is there any way I can achieve this smooth mask that doesn't rely on a mask image but rather a path or shape layer?
I was trying to achieve this with a NSWindow view a while back and I came across this awesome library: https://www.cocoacontrols.com/controls/waythedarkside
It allows you to add a light or dark blur to your view/background. I think this is what you are looking for :)

Flipboard style page turn animation

I'm trying to write a fairly simple animation using Core Animation to simulate a book cover being opened. The book cover is an image, and I'm applying the animations to its layer object.
As well as animating a rotation around the y axis (The the anchorPoint property set of the left of the screen), I need to scale the right hand edge of the image up so it appears to "get closer" to the user and create the illusion of depth. Flipboard, for example, does this scaling really well.
I can't find any way of scaling an image like this, so only one edge is scaled and the image ends up nonrectangular.
All help appreciated with this one!
CoreAnimation, by default, "flattens" its 3D hierarchy into a 2D world at z=0. This causes perspective and the like to not work properly. You need to host your layer in a CATransformLayer, which will render its sublayers as a true 3D layer hierarchy.

How to Find All CALayers assoicated with an nsview?

I'm hosting Apple's Pitch Shift Audio Unit plugin in Mac OSX 10.7 Lion. The pitchShiftView is made up of CALayers: one for each knob etc.
There are value bars that appear when changing parameter values with the knobs that I believe are CALayers, but they do not show up in the CALayer hierarchy. They stay on screen when they should disappear, and end up crashing my app with exit bad access.
How do I gain access to these layers, or why arn't they tied to the rest of the layer hierarchy?
They may not actually be layers, or at least not layers in the current NSView. They might be subviews of the NSView, or they might even be NSViews that hover over top of the NSView in question. Almost anything is possible.
The first tool you want is Accessibility Inspector (in /Developer). It lets you point at anything on the screen and find out where it is in the accessibility hierarchy, which very often is closely related to where it is in the view hierarchy. Once you understand where they are in the view hierarchy, you can start digging around with the debugger trying to understand where they are in the layer hierarchy, if they're in the layer hierarchy. Remember that on Mac, CALayer is an optional addition to NSView. So there might not be layers.

Preventing CALayer Sublayers From Getting Scaled

I have some CALayers in a layer hosted view. Each of these layers has additional layers to hold (1) a close button, and (2) a resize handle. These additional 'control' layers are added as sublayers to the parent layer.
Currently, when I zoom the workspace in which these layers reside, everything scales -- including these control layers. However, I would like to prevent these control layers from scaling.
Is there a way to override the behaviour of having scale transforms being applied to all sublayers, without having to override the drawInContext: method for each control layer (presumably to invert any existing scale transform -- assuming this is possible) and without having to manually send each of these control layers a setNeedsDisplay: with every zoom?
I found this thread which discusses doing something similar but the discussion goes in the direction of CATiledLayers which is not what I'm looking for here.
Redrawing CALayer subclass when super layer is scaled
Also, this post asks a somewhat related question but the responses do not apply to my situation, since I cannot overlay the controls -- they must be part of the layer hierarchy.
How do I keep a CALayer, sublayer of a CATiledLayer, from changing it's scale after a zoom?
I ended up solving this problem by overriding the layoutSublayers method of my custom CALayers, obtaining the accumulated scale transform of the layer hierarchy, and applying the inverse transform to the control sublayers.

Simple Drawing App Design -- Hillegass Book, Ch. 18

I am working through Aaron Hillegass' Cocoa Programming for Mac OS X and am doing the challenge for Chapter 18. Basically, the challenge is to write an app that can draw ovals using your mouse, and then additionally, add saving/loading and undo support. I'm trying to think of a good class design for this app that follows MVC. Here's what I had in mind:
Have a NSView-subclass that represents an oval (say JBOval) that I can use to easily draw an oval.
Have a main view (JBDrawingView) that holds JBOvals and draws them.
The thing is that I wasn't sure how to add archiving. Should I archive each JBOval? I think this would work, but archiving an NSView doesn't seem very efficient. Any ideas on a better class design?
Thanks.
Have a NSView-subclass that represents an oval (say JBOval) that I can use to easily draw an oval.
That doesn't sound very MVC. “JBOval” sounds like a model class to me.
Have a main view (JBDrawingView) that holds JBOvals and draws them.
I do like this part.
My suggestion is to have each model object (JBOval, etc.) able to create a Bézier path representing itself. The JBDrawingView (and you should come up with a better name for that, as all views draw by definition) should ask each model object for its Bézier path, fill settings, and stroke settings, and draw the object accordingly.
This keeps the knowledge of how to draw (the path, line width, colors, etc.) in the various shape classes where they belong, while also keeping the actual drawing code in the view layer where it belongs.
The answer to where to put archiving code should be intuitively obvious from this point.
Having a whole NSView for each oval seems rather heavyweight to me. I would descend them from NSObject instead and just have them draw to the current view.
They could also know how to archive themselves, although at that point you'd probably want to think about pulling them out of the view and thinking of them more as part of your model.
Your JBOval views would each be responsible for drawing themselves (basically drawing an oval path and filling it, within their bounds), but JBDrawingView would be responsible for mousing and dragging (and thereby sizing and positioning the JBOvals, which would be its subviews). The drawingView would do no drawing itself.
So far as archiving, you could either have a model class to represent each oval (such as its bounding rectangle, or any other dimensions you choose to represent each oval with). You could archive and unarchive these models to recreate your views.
Finally, I use the JB prefix too, so … :P at you.