IOS animation-Transform and KeyFrame Animation
Preface
The pursuit of beauty is human nature, which is unavoidable by the ape. We are always pursuing more cool implementations. If we are careful enough, it is not difficult to find that a good animation is essentially a simple animation after being decomposed by steps, it is these basic animations that have been combined with each other to make them magical and amazing. Therefore, mastering the most basic animation is the foundation of the cool development journey.
As the second animation article, I briefly introduced several basic animations about UIView from the perspective of UIView animation. The combination of these animations makes our login interface lively, however, these animations cannot meet our needs for animations. Similarly, this article will begin with a small demo to explain the powerfultransform
Animation and Key FramekeyFrame
Animation.
Demo Animation
We can see two animations: The leaves are blown by the wind and the text on the left issummer
Changedautumn
These two animations are based on powerfultransform
Deformation. the animation of the falling leaves is implemented through the key frame animation. Demo Link
Transform Animation
transform
It is a very important attribute. It changes the Display Effect of the view on the matrix transformation layer and completes operations such as rotation, deformation, and translation. When it is modified, the frame of the view is actually changed. There are two data types used to representtransform
, Which areCGAffineTransform
AndCATransform3D
. The former acts onUIView
The latter islayer
The type of the hierarchy. The latter can provide more powerful functions, but we need to masterCGAffineTransform
Type. This document also describes the conversion type.
Talk is cheap show you the code
Start to usetransform
Before implementing your animation, I will introduce several common functions:
/// Connect two transformations and return them. The returned t = t1 * t2 CGAffineTransformConcat (CGAffineTransformt1, CGAffineTransformt2) // The initial matrix value. [100100] CGAffineTransformIdentity // custom matrix transformation, you need to know the knowledge of matrix transformation to know how to use it. Refer to the recommended principle links above. CGAffineTransformMake (CGFloata, CGFloatb, CGFloatc, CGFloatd, CGFloattx, CGFloatty) // rotate the view. The input parameter is angle * (M_PI/180 ). Equivalent to CGAffineTransformRotate (self. transform, angle) CGAffineTransformMakeRotation (CGFloatangle) CGAffineTransformRotate (CGAffineTransformt, CGFloatangle) // zoom view. Equivalent to CGAffineTransformScale (self. transform, sx, sy) Scaling (CGFloatsx, CGFloatsy) CGAffineTransformScale (CGAffineTransformt, CGFloatsx, CGFloatsy) // scaling view. Equivalent to CGAffineTransformTranslate (self. transform, tx, ty) convert (CGFloattx, CGFloatty) CGAffineTransformTranslate (CGAffineTransformt, CGFloattx, CGFloatty)
I recorded the text Deformation Process in the lower-left corner of the demo. It is recommended that the licecap program for capturing motion graphs on mac is very simple and easy to use. The blogger uses it to break down the animation step and then reproduce it.
Text Deformation Process
It is not hard to see that two operations are done in the text Animation: the deformation and reduction on the Y axis, and the gradient process of transparency. Add two UILabel in the project, named label1 and label2. and add the following code to viewDidAppear:
-(Void) viewDidAppear :( BOOL) animated {label1.transform = CGAffineTransformMakeScale (0, 0); label1.alpha = 0; [UIViewanimateWithDuration: 3. animations: ^ {label1.transform = CGAffineTransformMakeScale (0.1); label2.transform = CGAffineTransformMakeScale (0,); label1.alpha = 1; label2.alpha = 0;}];}
The following explains why label2 gradually decreases the Y axis in the animation to 0.1 instead of 0. If we set it to 0, label2 will directly end the animation after the animation is submitted (this is automatically completed due to performance optimization), so when any scaled-out deformation is used, you can set the reduction value to a small value, as long as it is not 0.
Run your code and you have already made the text deformation process, but the animation in the demo is not only a deformation, but also a displacement process. Obviously, we can changecenter
But this is obviously not the result we want today. It makes more sense to implement new animation methods.
When the animation starts, the label height of the deformation occurs is 0, and the height gradually changesheight
Label does not change from start to end based on the top position. Therefore, the label is 0 on the Y axis before the animation starts, and the Y axis center isheight / 2
(Based on the label coordinate system), the animation code can be written as follows:
-(Void) viewDidAppear :( BOOL) animated {// The Position of the label before the animation is initialized CGFloatoffset = label1.frame. size. height * 0.5; label1.transform = hour (CGAffineTransformMakeScale (0, 0), CGAffineTransformTranslate (0,-offset); label1.alpha = 0; [UIViewanimateWithDuration: 3. animations: ^ {// restore the status of label1 transformation and deformation and offset label2 label1.transform = complete; label1.transform = convert (0, 0), CGAffineTransformTranslate (0, offset )); label1.alpha = 1; label2.alpha = 0;}];}
Adjust the positions of the two labels and set a transparent display. Run this code and you will find that the animation of the text conversion process is complete.
Keyframe Animation
Save the gif image at the beginning of the article as a local image and open it with preview. You will find that the gif image in the preview has changed to many images. In fact, animation, movie, CG, and other dynamic effects can all be seen as continuous rendering of an image. When these images are switched fast enough, we will be treated as an animation. Previously, after the UIView animation is submitted, the system will calculate all frames of the view moving Based on the animation duration and then render them one by one.
Return to the fallen leaves animation in our demo.center
After five modifications, I plot the linear path of the fallen leaf translation and mark the key turning point:
1. png
How can I implement the above translation using the UIView animation code? There is no doubt that we need to continuously use nested UIView animations. The specific code is as follows:
[Condition :( CGPoint) {30,105} completion: ^ (BOOLfinished) {[condition :( CGPoint) {40,110} completion: ^ (BOOLfinished) {[selfmoveLeafWithOffset :( CGPoint) {} completion: ^ (BOOLfinished) {[selfmoveLeafWithOffset :( CGPoint) {90,80} completion: ^ (BOOLfinished) {[condition :( CGPoint) {80 ,60} completion: nilduration: 0.6];} duration: 1.2];} duration: 1.2];} duration: 0.6];} duration: 0.4];-(void) moveLeafWithOffset :( CGPoint) offsetcompletion :( void (^) (BOOLfinished )) completionduration :( NSTimeInterval) duration {[UIViewanimateWithDuration: durationdelay: 0 options: UIViewAnimationOptionCurveLinearanimations: ^ {CGPointcenter = _ leaf. center; center. x + = offset. x; center. y + = offset. y; _ leaf. center = center;} completion: completion];}
It looks quite easy. The above Code only moves the leaves. In the gif image, our leaves are still rotated. Therefore, we need to add the following code:
[UIViewanimateWithDuration:4animations:^{_leaf.transform=CGAffineTransformMakeRotation(M_PI);}];
So OK, run this code to see if the fallen leaves are very stiff and we can see the corners clearly. Second, in this codeduration
It makes no sense to pass in (passing in a fixed animation duration cannot reflect the steps in the process of falling leaves)
For these two problems, UIView also provides another animation method to help us solve these two problems-keyframe Animation:
+ (Void) Updated :( NSTimeInterval) durationdelay :( NSTimeInterval) delayoptions :( partial) Updated :( void (^) (void) animationscompletion :( void (^ __nullable) (BOOLfinished )) completion + (void) addKeyframeWithRelativeStartTime :( double) frameStartTimerelativeDuration :( double) frameDurationanimations :( void (^) (void) animations
The first method is to create a Key Frame Animation. The second method is used to insert Key Frame Animation information into the animation code block. The meanings of the two parameters are as follows:
FrameStartTime indicates the percentage of the start time of the Key Frame Animation in the whole animation.
FrameDuration indicates the percentage of the animation duration occupied by the key frame animation.
I made an image to indicate the parameter meaning:
- Key Frame method parameter description
ComparisonUIView
Animation and Key Frame Animation introduce the concept of animation proportions, this allows us to control the proportion of each key frame animation, rather than passing in a meaningless animation duration-which makes our code more difficult to understand. Of course, in addition to the animation proportion, the Key Frame Animationoptions
Parameters also make the animation smoother. The following are the configuration parameters unique to the key frame:
UIViewKeyframeAnimationOptionCalculationModeLinear // continuous operation mode, linear UIViewKeyframeAnimationOptionCalculationModeDiscrete // discrete operation mode, only display key frames UIViewKeyframeAnimationOptionCalculationModePaced // even operation mode, linear UIViewKeyframeAnimationOptionCalculationModeCubic // smooth operation mode UIViewKeyframeAnimationOptionCalculationModeCubicPaced // smooth and even Operation ModeIn the demo, I usedUIViewKeyframeAnimationOptionCalculationModeCubic
This parameter uses the besell curve to smooth the fallen leaves animation. The effect is visible to the initial GIF animation. You can modify different parameters passed in the demo to view the effect. Next, based on the new methodUIView
The code for converting an animation into a key frame is as follows:
[UIViewanimateKeyframesWithDuration: 4 delay: 0 options: UIViewKeyframeAnimationOptionCalculationModeLinearanimations: ^ {_ blockCGPointcenter = _ leaf. center; [UIViewaddKeyframeWithRelativeStartTime: 0 relativeDuration: 0.1 animations: ^ {_ leaf. center = (CGPoint) {center. x + 15, center. y + 80 };}]; [UIViewaddKeyframeWithRelativeStartTime: 0.1 relativeDuration: 0.15 animations: ^ {_ leaf. center = (CGPoint) {center. x + 45, center. y + 185 };}]; [UIViewaddKeyframeWithRelativeStartTime: 0.25 relativeDuration: 0.3 animations: ^ {_ leaf. center = (CGPoint) {center. x + 90, center. y + 295 };}]; [UIViewaddKeyframeWithRelativeStartTime: 0.55 relativeDuration: 0.3 animations: ^ {_ leaf. center = (CGPoint) {center. x + 180, center. y + 375 };}]; [UIViewaddKeyframeWithRelativeStartTime: 0.85 relativeDuration: 0.15 animations: ^ {_ leaf. center = (CGPoint) {center. x + 260, center. y + 435 };}]; [UIViewaddKeyframeWithRelativeStartTime: 0 relativeDuration: 1 animations: ^ {_ leaf. transform = CGAffineTransformMakeRotation (M_PI) ;}];} completion: nil];We can see thatUIView
Key Frame Animation makes it more intuitive for us to understand the time ratio of each Pan animation, and the code is more concise.