For certain tasks in iOS development there are ample examples in Objective-C but not Swift. This can be a problem when API calls take structures as arguments as the Swift compiler performs more and different type-safety checks. An additional challenge was that the compiler errors can be a bit vague about what it is expected.
An example of this we came across recently was using CAKeyframeAnimation in a Swift iOS application. CAKeyframeAnimation was used in the case to increase the size of a label so that, when combined with a fade animation, would cause a label on a view to increase in size and opacity simultaneously.
The fade animation was fairly simple to implement in Swift.
//create a CABasicAnimation that fades from 0 to 1 opacity over 3 seconds var fadeAnimation = CABasicAnimation(keyPath: "opacity") fadeAnimation.fromValue = 0.0 fadeAnimation.toValue = 1.0 fadeAnimation.duration = 3.0
Text Size Animation
// create a CAKeyframeAnimation with a keyPath of "transform" var scaleAnimation = CAKeyframeAnimation(keyPath: "transform")
So far so good. They keyPath "transform" indicates that we will be applying a transform to some value as part of the animation.
Now here comes the part that took a little research. The CAKeyframeAnimation class takes an array of values for the transformation. This series of transformation values to describe each step of the animation. In this case, we only have two values that we are going between 10% and 100%. We start at 10% and smoothly transition to 100% of the text size. The CAKeyframeAnimation class has a function called values that is defined as:
var values: [AnyObject]!
First we tried:
scaleAnimation.values = [CATransform3dMakeScale(0.1, 0.1, 0), CATransform3dMakeScale(1.0, 1.0, 0)]
But this gave a compiler error of:
Use of unresolved identifier 'CATransform3dMakeScale'
Further search revealed that the .values function is expecting an array of NSValue objects. So we tried:
scaleAnimation.values = [NSValue(CATransform3DMakeScale(0.1, 01.0)), NSValue(CATransform3DMakeScale(1.0, 1.0, 0))]
Changing the compiler error to:
Missing argument label 'CATransform3D' in call
The Fix-it tip was "Insert CATransform3D:" which changed the call to:
// set the CAKeyframeAnimation to go from 10% to 100% scale scaleAnimation.values = [NSValue(CATransform3D: CATransform3DMakeScale(0.1, 0.1, 1)), NSValue(CATransform3D: CATransform3DMakeScale(1, 1, 1))]
To finish it off, we specified an "Ease Out" timing function and set a duration of 3 seconds.
// specify and "Ease Out" timing function scaleAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) // set the duration of the animation for 3 seconds scaleAnimation.duration = 3
Finally, we added both animations to the Label object's layer:
// add both animations to the Label growingLabel.layer.addAnimation(scaleAnimation, forKey: "transform") growingLabel.layer.addAnimation(fadeAnimation, forKey: "opacity")
The result was a text label that faded in and grew from 7.2 points to 72 points over 3 seconds while going from transparent to fully opaque over the same 3 second interval.