更 Swifty 的 Core Animation
There's not a lot of new frameworks and APIs in this year's new OS releases from Apple. Instead, the focus is clearly on under-the-hood improvements and performance gains, like was also mentioned during the WWDC keynote. Another area in which Apple has made some really nice improvements is how some of their lower-level frameworks import into Swift - particularity Core Animation.
Core Animation is arguably one of the most important frameworks on Apple's platforms, since it powers a huge part of the UI across all devices. In my talk "Beyond Animations with Core Animation", I showed how Core Animation is not only an animation framework - it's also a powerful general-purpose rendering tool that can be used in many different ways to create custom graphics in an app.
In today's WWDC Update, let's take a look at how Core Animation this year has been made a bit more "Swifty", thanks to some better annotations and how many of its APIs that previously relied on strings now use synthesized enums and option sets.
Drawing programmatic shapes can be a great way to remove resolution-dependent assets and make content more dynamic in an app. The API for drawing custom shapes has year-by-year become nicer and nicer to use in Swift, and this year all string constants have been turned into proper types. For example, here's how we can now use dot syntax to add rounded edges to a line in a type-safe way:
let line = CAShapeLayer() line.lineCap = .round
For more complex shapes, we can now also use dot syntax to describe a custom fill mode when filling overlapping shapes with a color:
let shape = CAShapeLayer() shape.fillRule = .evenOdd
Before, both of the above properties were using strings, leading to harder API discoverability and less type safety.
I'll go into a lot more detail on
CAShapeLayer and all the cool things it can be used for in an upcoming entry in my "Core Animation Gems" series.
More important though, are the changes made to Core Animation's actual animation API, with its many variants of
CAAnimation. This type of animations has by many developers been considered a lot harder to use then UIKit's built-in animation APIs, and even though they offer much more functionality and control, they haven't really felt "at home" in Swift - until now.
Just like how other parts of Core Animation have now been fully annotated for Swift, animations now use strongly typed options, both for things like how an animation fills in a layer's properties, but also when it comes to referencing timing functions:
let animation = CABasicAnimation(keyPath: #keyPath(CALayer.transform)) animation.fillMode = .forwards animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
#keyPath compiler command, we can even take the final stringly-typed part of the animation API - what key path we want to animate over - and turn it type safe as well. Take a look at this complete example, in which we're creating a customly timed animation for rotating a layer, it's hard to tell that we're actually using an old Objective-C and C-based API under the hood:
let animation = CABasicAnimation(keyPath: #keyPath(CALayer.transform)) animation.fillMode = .forwards animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) animation.duration = 5 animation.fromValue = layer.transform animation.toValue = CATransform3DMakeRotation(.pi, 0, 0, 1) layer.add(animation, forKey: "rotate")
The same type of tweaks and improvements that have been applied to
CAAnimation & friends can also been found all over Core Animation's other types and classes. For example,
CATextLayer now uses enums for its alignment and truncation properties, and defining layer constraints using
CAConstraint can now also be done in a type-safe manner.
The addition of these modifications when using Core Animations in Swift might seem trivial and unimportant at first, but it really helps - both in terms of keeping our source code nice, safe and clean, but also in making frameworks like Core Animation a lot more accessible to a new generation of Swift developers.
I'm very happy that Apple are going back and annotating these Objective-C and C-based APIs, rather than throwing them away and rewriting them "from the ground up". Core Animation is an incredibly powerful and flexible tool, and making it seem less like a low-level inaccessible framework and more like something that's easy to use for all Swift developers, I think is a big win.
What do you think? Are you using Core Animation in your app, or will you try now that the whole API imports very nicely into Swift? Let me know - along with your questions, comments and feedback - on Twitter @johnsundell.
Thanks for reading!