Learning notes for book iOS Animations by Tutorials.

When a view has several stages of moving animation, it is complicated to use animateWithDuration to implement the animation because it will contain nasty nesting in your code.

However, Keyframe animation can solve the problem in an easy way. In UIView, there are two methods.

  • animateKeyframesWithDuration:delay:options:animations:completion:
  • addKeyframeWithRelativeStartTime:relativeDuration:animations:

The first one creates an animation block object that can be used to set up keyframe-based animations for the current view. Well, the second one specifies the timing and animation values for a single frame of a keyframe animation.

The parameters in animateKeyframesWithDuration are easy to understand, but the parameters in addKeyframeWithRelativeStartTime are needed to take carefully.
In addKeyframeWithRelativeStartTime:

  • frameStartTime: The time at which to start the specified animations. This value must be in the range 0 to 1. The value is the percentage of the total duration time. If the total duration is 2 sec and the frameStartTime is 0.5, then the real starting time is at 1 sec.

  • frameDuration: The length of time over which to animate to the specified value. This value must be in the range 0 to 1. The value is the percentage of the total duration time. If the total duration is 10 sec and the frameDuration is 0.25, then the real duration of this animation stage is 2.5 sec.

Okey, let try to do this animation using keyframe animation.

Image-1Image-1

The stages of the moon rising and falling look like this:
Image-2Image-2

I used four stages. On X-axis, each stage moving length for the moon is identical which is a quarter of superview.width. On Y-axis, the moon climbs higher at the beginning of rising which means moon.y will minus a larger number in the first stage than in the second stage. For falling, it is the opposite of rising. To make the moon move smoothly, I choose CalculationModeCubic for the keyframe animation option.

Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
moon.alpha = 0.0

UIView.animateKeyframesWithDuration(5, delay: 0.0, options: [.CalculationModeCubic, .Repeat], animations: {
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25, animations: {
self.moon.alpha = 0.5
self.moon.center.x += self.view.frame.size.width / 4.0
self.moon.center.y -= 80
})
UIView.addKeyframeWithRelativeStartTime(0.25, relativeDuration: 0.25, animations: {
self.moon.alpha = 1.0
self.moon.center.x += self.view.frame.size.width / 4.0
self.moon.center.y -= 20
})
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.25, animations: {
self.moon.center.x += self.view.frame.size.width / 4.0
self.moon.center.y += 20
})
UIView.addKeyframeWithRelativeStartTime(0.75, relativeDuration: 0.25, animations: {
self.moon.alpha = 0.0
self.moon.center.x += self.view.frame.size.width / 4.0
self.moon.center.y += 80
})
}, completion: nil)