Search code examples
core-animationnsviewappkit

Control layout of sublayers of NSView with transforms applied


I'm attempting to create an NSView subclass which can give me access to a layer for which I can control the normally-off-limits parameters like anchorPoint and transform, as well as apply animations.

My plan was to create a layer-hosting view, and then add a sublayer to its root layer. This works perfectly, with the exception that I'm having a very difficult time positioning and sizing this sublayer. I feel like I'm missing something obvious, but I cannot figure it out.

My first attempt was to set the layoutManager of the root layer to CAConstraintLayoutManager. This works great unless I set the sublayer's transform property. CAConstraintLayoutManager updates the layer's frame directly and this causes issue with rotation transformations. Took me forever to figure this out, but I eventually did find the documentation that explains this.

Ok, so next, I made a custom CALayoutManager that just adjusts sublayer's bounds and position, instead of changing the frame. This appears to work, but corrupts layout if my view has subviews. This surprised me. I guess it is messing with NSView's internal layout system when other layers are involved?

So, I moved on using the root layer delegate method func layoutSublayers(of layer: CALayer). This also corrupts layout, as I didn't realize that NSView itself expects to be the root layer's delegate and uses that method specifically.

So, at this point, I'm at a loss. I cannot figure out how to control layout and also apply a transform to a sublayer. Does anyone have any suggestions?


Solution

  • It turns out there's an obvious answer to this question. NSView has a layout method that is perfect for this. I experimented with this early on, but my code was in a bad state and things weren't working for other reasons. Once I removed all the experiments/half-commented code, things worked great!