Mac App Animation Takeaways

Harry Ng
macOS App Development
3 min readAug 10, 2016

I am developing a Mac App which needs some animations to be done. In fact, I am quite new to animation topics on Mac App. For instance, I have the animation code working in iOS, but I want to port to Mac App. Here are some takeaways in an animation which rotates a layer along x-axis.

Simple transform animation

Applying 3D Transform

Simply copying the code from iOS, the first problem I faced was the initial transform was not working. I want to set the initial state as 45 degrees rotated, but the layer kept at front-facing position.

I ended up realising that in Cocoa, I have to add the view to the view hierarchy before applying the transform. Without adding as subview, the corresponding view is not rendered. Thus, applying transform has no effect to it.

Transforming all the subviews

While I was looking for solution to the previous problem, I thought it might be the problem of not having CALayer-backed by default. I even thought may be I could not apply the transform to the root layer of the corresponding view.

I ended up knowing that if I created another CALayer for the transform, and inserted this layer to the layer hierarchy. Only this layer will be transformed, and all the subviews like NSTextField will keep unchanged. Another finding is that, this layer can be transformed before the root view is added to view hierarchy.

Comparing iOS animation API

In iOS, animation can be done using the ‘UIView.animateWithDuration()’ API. The method allows me to set duration, delay, damping factors, as well as a completion block. However, this nice API or similar is not available in Cocoa.

I ended up using ‘CABasicAnimation’ to animate the rotation, and then use ‘CATransaction’ to apply completion block. I can optionally use delegate methods to get noticed when animation is complete, but I think completion block makes the code more clear.

Animating the transform

As mentioned, I use CABasicAnimation to animate the rotation. It is making use of the keyPath. Since I want the layer to rotate along x-axis, I have to use “transform.rotation.x”. The API is fairly simple, but it is not Swifty enough. The use of keyPath is not type-safe.

Upon Swift 3, there will be huge improvements to this kind of APIs. The APIs for Swift 3 have become stable. This will be officially available in Xcode 8 public release.

Here is the sample playground for this post.

References:

How to apply a view transformation that works for a UIView to a NSView?

Rotating CALayer of NSImageView 90 degrees

CATransform3DRotate rotate for 360 degrees

CATransform3D Key Paths

XCPlayground Basics 🎪

I am taking a challenge to write a post every day for 180 days. The content will be related to my life as a father, entrepreneur, developer and trainer.

Recent articles:

--

--