Core Animation

As we all know, gorgeous animation effects are a major feature of iOS system. Animations encapsulated by UIView layer can basically meet all the requirements of our application development. However, if we need to control animation presentation more freely, we need to use some classes and methods in CoreAnimation framework

Core Animation basics

Core Animation is the graphics rendering and Animation infrastructure for iOS and OS X and can be used to animate views and other visual elements of an application. The implementation logic of Core Animation is to hand over most of the actual drawing work to dedicated graphics hardware for accelerated rendering to achieve high frame rates and smooth Animation without taxing the CPU and slowing down the application.

The following diagram illustrates the relationship between CoreAnimation and UIKit frameworks

CALayer

CALayer is conceptually similar to UIView in that it’s a bunch of rectangular blocks that are managed by a hierarchical tree, that can also contain content, manage sublayers, animate and transform. But the big difference is that UIView can handle user interactions, whereas CALayer can’t respond to events, even though it provides some way to determine if a touch is within the scope of a layer. Each UIView encapsulates a CALayer layer, which we access through the Layer property of UIView. In fact, UIView is responsible for presenting content to its internal CALayer, UIView is just handing over its presentation to its internal CALayer, and it’s also responsible for some other tasks, such as user interaction, Provides some high-level interfaces to the underlying methods of Core Animation.

So why not put these tasks in a single class instead of running them in parallel? It’s important to separate responsibilities so that you can avoid a lot of repetitive code. Because the way users interact on iOS and MacOS is fundamentally different. On iOS, we use UIKit and UIView, while on MacOS, we use AppKit and NSView. So, in this case, separating out the presentation section would make it easier for Apple to develop multi-platform systems.

@interface CALayer : NSObject <NSSecureCoding, CAMediaTiming>
{
@private
  struct _CALayerIvars {
    int32_t refcount;
    uint32_t magic;
    void *layer;
#if TARGET_OS_MAC && ! TARGET_RT_64_BIT
    void * _Nonnull unused1[8];
#endif
  } _attr;
}
Copy the code

CALayer properties: The main job of the CALayer layer is to manage the visual content you provide, and the layer itself has settable visual properties such as background colors, borders, and shadows. In addition to managing visual content, information about the geometry of its content (such as its position, size, and transformation) is retained for rendering that content on the screen.

Core Animation

So let’s talk about Core CAAnimation, CAPropertyAnimation, CABasicAnimation, CAKeyframeAnimation, CASpringAnimation, CATransition, CAAnimatio NGroup and the relationship between them are also interweaved with CALayer Animation operation principle, animation-keypath value, CATransaction transaction class, detect the end of Animation, pause and restore layer Animation and other contents

CAAnimation

CAAnimation is the core animation base class, can not be used directly, mainly responsible for the animation time, speed, etc., itself to achieve the CAMediaTiming protocol.

@interface CAAnimation : NSObject
    <NSSecureCoding, NSCopying, CAMediaTiming, CAAction>
{
@private
  void *_attr;
  uint32_t _flags;
}
Copy the code
CAAnimation properties instructions
timingFunction CAMediaTimingFunction Speed control function, control animation run rhythm
removedOnCompletion The default value is YES, which means the animation is removed from the layer and the image is restored to its original state. Set it to NO if you want the layer to look like it did after the animation was executed, but also set fillMode to kcafillmodeforward
delegate Agents (animationDidStart, animationDidStop)

Ps: CAMediaTimingFunction introduction

KCAMediaTimingFunctionLinear (linear) : uniform, give you the feeling of a relatively static kCAMediaTimingFunctionEaseIn (gradual) : Slowly into the animation, and then accelerate left kCAMediaTimingFunctionEaseOut (gradually) : enter at full speed, and then slow to arrive kCAMediaTimingFunctionEaseInEaseOut (gradual fading out) : The animation enters slowly, speeds up in the middle, and then slows down to reach its destination. This is the default animation behavior.Copy the code

CAMediaTiming protocol

Time-related properties like Duration, beginTime, repeatCount, Speed, timeOffset, repeatDuration, and AutoReverses are all in this class. These attributes in the protocol are combined in some way to precisely control the time.

CAMediaTiming properties instructions
beginTime Specifies when the animation starts. For a delay of a few seconds from the start, set it to CACurrentMediaTime() + seconds
duration Duration of animation
speed Animation runtime speed (if animation duration is set to 3 seconds and speed to 2, animation will end in 1.5 seconds because it is executing at twice the speed)
timeOffset Used in conjunction with a pause animation (speed=0) to control the “current time” of the animation. A suspended animation will get stuck on the first frame and then control the animation at will by changing the timeOffset
repeatCount Number of repetitions. Keep setting this to HUGE_VALF
repeatDuration Set the time of the animation. The animation is executed no matter how many times during that time.
autoreverses Whether to perform a reverse animation at the end of the animation, if duration is 1s, then completing an autoreverse requires 2s.
fillMode CAMediaTimingFillMode enumeration

Ps: CAMediaTimingFillMode Introduction

KCAFillModeRemoved: This is the default value, which means that before and after animations, there is no effect on the layer. After animations, the layer will be restored to its previous state. Kcafillmodeforward: KCAFillModeBoth (backwards) : Backwards (backwards) When the animation is over, the layer will retain the toValue state (backwards). After the animation to join before you begin, layer is animation initial state, the end of the animation layer animation last condition Attention must cooperate with animation. RemoveOnCompletion = NO can achieve above effectCopy the code

CAPropertyAnimation

To create an animation object, you should use two of its subclasses: CABasicAnimation and CAKeyframeAnimation

You do not create instances of CAPropertyAnimation: to animate the properties of a Core Animation layer, create instance of the concrete subclasses CABasicAnimation or CAKeyframeAnimation.
Copy the code
CAPropertyAnimation properties instructions
keyPath The corresponding animation effect can be achieved by specifying a CALayer attribute named keyPath (NSString type) and modifying the value of this attribute of CALayer. For example, by specifying @ “position” as keyPath, you can change the value of CALayer’s position property to animate the pan

CABasicAnimation

CABasicAnimation is a class in the core animation class. Its parent class is CAPropertyAnimation, its subclass is CASpringAnimation, and its grandfather is CAAnimation. It is mainly used to make relatively single animation, such as translation, scaling, rotation, color gradient, border value change, etc., which is to change a layer property value from one value to another value

CABasicAnimation properties instructions
fromValue The starting value of the changed property
toValue The end value of the changed property
byValue The amount of change to the same starting value for the changed property

The following code

        let baseAnim = CABasicAnimation(keyPath: "position") baseAnim.duration = 2; Baseim.fromvalue = NSValue(cgPoint: (imgView?.layer.position)!) baseAnim.toValue = NSValue(cgPoint: CGPoint(x: 260, y: 260)) // baseAnim.isRemovedOnCompletion =false// baseAnim.fillMode = CAMediaTimingFillMode.forwards imgView? .layer.add(baseAnim,forKey: "baseAnim-position") imgView? .center = CGPoint(x: 260, y: 260)Copy the code

Prevents the animation from returning to the initial state

You need to add imgView as shown in the code above. Center = CGPoint(x: 260, y: 260) to prevent the animation from returning to the initial state after the completion of the animation. Another online method is to set the properties of removedOnCompletion and fillMode

baseAnim.removedOnCompletion = NO;
baseAnim.fillMode = kCAFillModeForwards;
Copy the code

However, this method will cause modelLayer not to be modified, and _view1’s actual coordinate points are not where they are seen, which will cause some problems

How CALayer animation works

CALayer has two instance methods presentationLayer (P) and modelLayer (M),

/* presentationLayer * returns a copy of the layer, if any animation is active, containing all layer properties * that are actually approximations to the current state. * Attempts to modify the result returned in any way are undefined. * Return values of sublayers, mask, and superLayer are presentationLayer */ - (Nullable InstanceType)presentationLayer for those properties of the current layer; /* modelLayer * calls presentationLayer to return the current model value. * On a non-PresentationLayer call, returns itself. * The result of calling this method after the transaction that generated the presentation layer is undefined. */ - (instancetype)modelLayer;Copy the code

It can be seen that P is the state we see on the screen, and M is the real state that takes effect immediately after we set it; For example, P is blind and only walks (draws), while M is lame and only sees (draws).

The operation principle of CALayer animation: P will update the state every time the screen is refreshed. When CAAnimation(A for short) is added, P is controlled by animation A to draw, and when animation A is removed, P will take the state display of M. But since M does not change, the animation will return to the starting point at the end of execution. If we want P to stop at the current state after the animation and not return to the state of M, we need to set two properties for A: a.emovedoncompletion = NO; After the animation is over, A still affects P. The other one is A.Illmode = kcafillmodeforward. These two lines of code will keep A under P’s control until the animation is over, but at this moment, our P and M are not synchronized. M is the same as before. For example, if we initialize a view, its state is 1, we animate its layer, from is 0, to is 2, and set fillMode to kCAFillModeForewards, then after the animation ends, P’s state is 2 and M’s state is 1, which may cause some problems. Let’s say you click on P and the dot doesn’t move, because the response to clicking on M. So should we synchronize P and M, like imgView? Center = CGPoint(x: 260, y: 260).center = CGPoint(x: 260, y: 260).center = CGPoint(x: 260, y: 260)

Animation – KeyPath value

For the KeyPath value of the animation above, we only use position. There are many other types that can be set. We list some of the most common ones below

KeyPath value instructions Value types
position Mobile location CGPoint
opacity transparency 0-1
bounds Get bigger with position CGRect
bounds.size Changed from small to big CGSize
backgroundColor The background color CGColor
cornerRadius Gradients, rounded corners Any numerical
borderWidth Change the size of the border border ((border around the graph, border is black by default)) Any numerical
contents Change the layer content (image) Note that if you want to change the content of the animation effect; First, define layer contents contents before running the animation CGImage
transform.scale Zoom in and out 0.0-1.0
transform.rotation.x Rotate animation (flip, along the X-axis) M_PI*n
transform.rotation.Y Rotate animation (flip, along the Y-axis) M_PI*n
transform.rotation.Z Rotate animation (flip, along the Z-axis) M_PI*n
transform.translation.x Rotate animation (flip, along the X-axis) Any numerical
transform.translation.y Rotate animation (flip, along the Y-axis) Any numerical

CAKeyframeAnimation

While CABasicAnimation changes properties from start to end values, CAKeyframeAnimation objects are animations that allow you to set a set of target values in a linear or non-linear manner. A keyframe animation consists of a set of target data values and the time each value arrives. Not only can you simply specify the value array and time array, but you can also change the position of the layer by following the path. The animation object takes the keyframe you specify and builds the animation by interpolating from one value to the next within a given time period.

CAKeyframeAnimation properties instructions
values The keyframe value represents the value that the animation must execute, and the value in this property is only used if the value of the PATH property is nil. Depending on the type of attribute, you may need to wrap the values in this array with the NSNumber of the NSValue object. For some core graphics data types, you may also need to convert them to ids before adding them to the array. The time to apply a given keyframe value to this layer depends on the animation time, controlled by the calculationMode, keyTimes, and timingFunctions properties. Values between key frames are created using interpolation unless the calculation mode is set to KCAAnimation discrete
path Path based on point properties. For layer properties that contain CGPoint data types, the path object you assign to the property defines the value of the property at the animation length. If you specify a value for this property, any data in the value property is ignored
keyTimes The value of keyTimes and the value of values correspond to the time point of the specified keyframe in the animation. The value range is [0,1]. When keyTimes is not set, the time of each keyframe is evenly split
timingFunctions An optional array of CAMediaTimingFunction objects specifying the animation buffering effect between each keyframe
calculationMode Interpolation calculation mode between key frames
rotationMode Defines whether objects animated along a path are rotated to match path tangents

Ps:

TimingFunctions: animation buffering effects

KCAMediaTimingFunctionLinear: linear pacemaker, make animation in its duration evenly kCAMediaTimingFunctionEaseIn: Make an animation began to slowly, and then accelerate, as the process of kCAMediaTimingFunctionEaseOut: the animation started quickly, and then slowly kCAMediaTimingFunctionEaseInEaseOut: Make the animation started slowly, in the middle of the duration of its acceleration, and then slow down again before completing kCAMediaTimingFunctionDefault: by default, ensure that the matching of time and most systems animation animationCopy the code

CalculationMode: animation calculationMode

KCAAnimationCubic is not the same thing as keyTimes or timingFunctions. Between the keyValue curve smoothing Available tensionValues continuityValues, biasValues adjustment kCAAnimationCubicPaced: keyValue smooth difference between ignoring keyTimesCopy the code

RotationMode: rotationMode

KCAAnimationRotateAuto: automatic kCAAnimationRotateAutoReverse: automatic reverse it Don't set is not rotatingCopy the code

Code 1: Use the values attribute

// Create an animation objectlet keyAnim = CAKeyframeAnimation(keyPath: "position"Values = [NSValue(cgPoint: cgPoint (x: 100, y: 200)), NSValue(cgPoint: cgPoint (x: 200, y: 200)) 200)), NSValue(cgPoint: CGPoint(x: 200, y: 300)), NSValue(cgPoint: CGPoint(x: 100, y: 300)), NSValue(cgPoint: CGPoint(x: 100, y: 400)), NSValue(cgPoint: CGPoint(x: 200, y: RepeatCount = MAXFLOAT // Set whether the original path is returned by defaultfalse
        keyAnim.autoreverses = true/ / set the movement speed, the smaller fast keyAnim. Duration = 4.0 keyAnim. IsRemovedOnCompletion =falsekeyAnim.fillMode = .forwards keyAnim.timingFunctions = [CAMediaTimingFunction(name: .easeInEaseOut)] imgView? .layer.add(keyAnim,forKey: "keyAnim-Values")
Copy the code

Listing 2. Use the path attribute

// Create an animation objectlet keyAnim = CAKeyframeAnimation(keyPath: "position"// Create a CGPathRef object, which is the animation pathletPath = CGMutablePath() // Automatically move path.addellipse (in: CGRect(x: 150, y: 200, width: 200, height: 100)) // Set the starting position of path.move(to: CGPoint(x: 100, y: 100)) AddLine (to: CGPoint(x: 200, y: 100)) path.addline (to: CGPoint(x: 200, y: 200)) path.addline (to: CGPoint(x: 200, y: 200)) path.addline (to: CGPoint(x: 200, y: 200)) path.addline (to: CGPoint(x: 200, y: 200)) path.addline (to: CGPoint(x: 100, y: 200)) path.addLine(to: CGPoint(x: 100, y: 300)) path.addLine(to: CGPoint(x: 200, y: AddCurve (to: CGPoint(x: 50.0, Y: 275.0), control1: CGPoint(x: 150.0, Y: 275.0), Control2: AddCurve (to: CGPoint(x: 150.0, y: 275.0), control1: CGPoint(x: 250.0, Y: 250.0)) path.addCurve(to: CGPoint(x: 70.0, Y: 120.0), control1: CGPoint(x: 250.0, Y: 250.0) AddCurve (to: CGPoint(x: 250.0, Y: 275.0), control2: CGPoint(x: 90.0, Y: 120.0)) Path.addCurve (to: CGPoint(x: 250.0, Y: 275.0), Control1: CGPoint(x: 350.0, Y: 275.0), control2: CGPoint(x: 110, Y: 120.0)) path.addCurve(to: CGPoint(x: 350.0, Y: 275.0), control1: CGPoint(x: 450.0, Y: 275.0), control2: CGPoint(x: 130, Y: 120.0)) keyim. path = path // Number of repetitions default is 1 keyim. repeatCount = MAXFLOAT // Set whether the original path return default isfalse
        keyAnim.autoreverses = true/ / set the movement speed, the smaller fast keyAnim. Duration = 4.0 keyAnim. IsRemovedOnCompletion =falsekeyAnim.fillMode = .forwards keyAnim.timingFunctions = [CAMediaTimingFunction(name: .easeInEaseOut)] imgView? .layer.add(keyAnim,forKey: "keyAnim-Path")
        
Copy the code

CASpringAnimation

The new CASpringAnimation in iOS9 inherits from CABaseAnimation, which is a class encapsulated by apple specifically to solve developers’ needs on spring animation

CASpringAnimation properties instructions
mass Mass, which affects the inertia of the spring as the layer moves. The greater the mass, the greater the stretch and compression of the spring. Default: 1
stiffness Stiffness coefficient (stiffness coefficient/elastic coefficient), the greater the stiffness coefficient, the greater the force generated by deformation, the faster the movement. Default value: 100
damping The damping coefficient, the coefficient that stops the spring from stretching, the higher the damping coefficient, the faster it stops. Default value: 10.
initialVelocity Initial speed, the initial speed of the animated view. Default value: 0. When the velocity is positive, the velocity direction is consistent with the direction of motion, while when the velocity is negative, the velocity direction is opposite to the direction of motion.
settlingDuration Estimated time Returns the estimated time of spring animation to stop, estimated according to the current animation parameters;

The following code

        let springAnim = CASpringAnimation(keyPath: "bounds") springAnim.toValue = NSValue(cgRect:CGRect(x: 200, y: 230, width: 140, height: 140)) //mass simulates the mass, which affects the inertia of the spring as the layer moves. The greater the mass, the greater the stretch and compression of the spring. Springim. Mass = 5 // The greater the stiffness factor, the greater the force generated by the deformation and the faster the movement. Default value: 100 springAnim stiffness = 80 / / damping coefficient, damping block spring expansion coefficient, the damping coefficient, the greater the stop the faster. Default value: 10. Springim. damping = 8 //initialVelocity Initial speed size of the animated view. Default value: 0. When the velocity is positive, the velocity direction is consistent with the direction of motion, while when the velocity is negative, the velocity direction is opposite to the direction of motion. SpringAnim. InitialVelocity = 10 / / estimate time return spring animation to the estimate time when to stop, according to the current animation parameters estimation; springAnim.duration = springAnim.settlingDuration imgView? .layer.add(springAnim,forKey: "springAnim")
Copy the code

CATransition

CATransition is a subclass of CAAnimation. It is used for transitions. It can animate layers from screen to screen and from screen to screen.

CATransition properties instructions
type CATransitionType, animation transition type
subtype CATransitionSubtype, animation movement direction
startProgress Animation starting point (percentage of total animation)
endProgress End of animation (percentage of total animation)

Ps: If you don’t need the animation to perform the entire process (animation stops in the middle), you can specify startProgress, endProgress properties.

CATransitionType: Animation transition type

KCATransitionFade: gradient kCATransitionMoveIn: overlay kCATransitionPush: push kCATransitionReveal: uncoverCopy the code

In addition, the following private methods are supported

-Dan: You know what? -Dan: Cube, suckEffect, oglFlip, rippleEffect, pageCurl, pageUnCurl, cemeraIrisHollowOpen. CameraIrisHollowClose: close the cameraCopy the code

CATransitionSubtype: Control animation direction, up/down/left/right 4 different directions of animation

kCATransitionFromRight
kCATransitionFromLeft
kCATransitionFromTop
kCATransitionFromBottom
Copy the code

CAAnimationGroup

A single animation cannot meet certain requirements, so you need to use CAAnimationGroup, which is a subclass of CAAnimation. By default, a group of animation objects are run at the same time. You can also change the animation time by setting the beginTime property of the animation object

CATransition properties instructions
animations [CAAnimation], animation group

The following code

        letGroupAnim = CAAnimationGroup() // Create keyAnimlet keyAnim = CAKeyframeAnimation(keyPath: "position"Values = [NSValue(cgPoint: cgPoint (x: 100, y: 200)), NSValue(cgPoint: cgPoint (x: 200, y: 200)) 200)), NSValue(cgPoint: CGPoint(x: 200, y: 300)), NSValue(cgPoint: CGPoint(x: 100, y: 300)), NSValue(cgPoint: CGPoint(x: 100, y: 400)), NSValue(cgPoint: CGPoint(x: 200, y: 500))] keyim.duration = 4.0 keyim.timingFunctions = [CAMediaTimingFunction(name:.easeIneaseout)let animation = CABasicAnimation(keyPath: "cornerRadius") animation.toValue = 40 animation.duration = 4.0 imgView? .layer.masksToBounds =truegroupAnim.animations = [keyAnim, Animation] groupanim. duration = 4.0 groupanim. repeatCount = MAXFLOAT groupanim. autoreverses =trueimgView? .layer.add(groupAnim,forKey: "groupAnim")
        
Copy the code

A more advanced way to group animations together is to use transaction objects. Transactions provide greater flexibility by allowing you to create nested sets of animations and assign different animation parameters to each animation.

CATransaction transaction class

The CATransaction transaction class can modify the properties of multiple layers at the same time. It includes implicit and explicit transactions. Core Animation automatically creates implicit transactions when we add explicit or implicit animations to layers. However, we can also create explicit transactions to manage these animations more precisely.

  • Distinguish between implicit animations and implicit transactions: Implicit animations animate through implicit transactions.
  • Distinguishing explicit animations from explicit transactions: Explicit animations can be implemented in a variety of ways, and explicit transactions are one way to implement explicit animations.
  • Any modification to the CALayer property, except for an explicit transaction, is an implicit transaction.

Implicit transaction

/ / create layerletlayer = CALayer() layer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100) layer.position = CGPoint(x: 100, y: Opacity = 1.0) Layer.backgroundcolor = uicolor.red.cgcolor layer.borderColor = Uicolor.black.cgcolor layer.opacity = 1.0 View.layer.addsublayer (layer) // Triggers animation // Sets whether the animation process is displayed. The default istrueDon't show CATransaction. SetDisableActions (false) layer.cornerRadius = (layer.cornerRadius == 0.0)? Opacity = (opacity. Opacity == 1.0)? 0.5:1.0Copy the code

Explicit transactions: Commit animations with explicit calls to begin and commit

Begin () layer.zposition = 200.0 layer.zposition = 0.0 CATransaction.com MIT ()Copy the code

One of the main reasons for using transactions is that within the scope of an explicit transaction, we can change the duration, timing function, and other parameters. You can also assign completion blocks to the entire transaction to notify the application when the animation group completes.

For example, to change the default duration of an animation to 8 seconds using the setValue:forKey: method, currently supported properties include: “animationDuration”, “animationTimingFunction”,”completionBlock”, “disableActions”.

CATransaction. The begin () CATransaction. SetValue (8.0,forKey: "animationDuration") // Execute animation CATransaction.com MIT ()Copy the code

Nested transactions: We can use nested transactions when we want to provide different defaults for different sets of animations. To nest a transaction within another transaction, simply call BEGIN again, and each BEGIN call must correspond to a COMMIT method. Core Animation starts the associated Animation only after committing changes for the outermost transaction.

Nested explicit transaction code

Begin () // External transaction catransaction.setValue (2.0,forKey: "animationDuration") layer.position = CGPoint(x: 140, y: 140) catransaction.begin () // Internal transaction catransaction.setValue (5.0,forKey: "animationDuration") layer.zposition = 200.0 layer.opacity = 0.0 CATransaction.com MIT () // Internal transaction CATransaction.com MIT () // External transactionCopy the code

Detects the end of the animation

Core animation supports detecting when an animation starts or ends. These notifications are a good time to do any housekeeping tasks related to the animation. For example, you can use a start notification to set up some relevant state information, and a corresponding end notification to dismantle the state.

There are two different ways to notify the status of an animation:

  • usesetCompletionBlock:Method adds the completion block to the current transaction. When all animations in the transaction are complete, the transaction executes the completion block.
  • Delegate is assigned to the CAAnimation object and implementedanimationDidStart:andanimationDidStop:finished:Delegate method.

If you want two animations to be linked together so that they start when the other one is finished, do not use animation notifications. Instead, use the animation object’s beginTime property to start each animation object at the required time. To link two animations together, simply set the start time of the second animation to the end time of the first animation.

Each layer has its own local time, which is used to manage animation timing. Often, the local times of two different layers are close enough that you can specify the same time value for each layer and the user might not notice anything. However, due to the timing parameters of the superLayer or its own Layer, the local time of the Layer will change. For example, changing the speed property of a Layer causes the duration of the animation on that Layer (and its sub-layers) to change proportionally.

To ensure that the time value of the Layer is appropriate, the CALayer class defines convertTime:fromLayer: and convertTime:toLayer: methods. We can use these methods to convert fixed time values to the local time of the Layer or to convert time values from one Layer to another. These methods may affect the media timing properties of the layer’s local time and return values that can be used with other layers.

You can use the following example to get the current local time of the layer. The CACurrentMediaTime function returns the computer’s current clock time. This method converts the local time to the layer’s local time.

Gets the current local time of the layer

CFTimeInterval localLayerTime = [myLayer convertTime: CACurrentMediaTime () fromLayer: nil];Copy the code

Once you have a time value in the layer’s local time, you can use this value to update the timing-related properties of an animated object or layer. Using these timing properties, you can implement some interesting animation behaviors, including:

  • The beginTime property sets the start time of the animation. Usually when the animation starts the next cycle, we can use beginTime to delay the animation start time by a few seconds. Two animations are linked together by setting the start time of one animation to match the end time of the other animation. If you delay the start of the animation, you may also need to set the fillMode property to kCAFillModeBackwards. This fill mode causes the layer to display the starting value of the animation even if the layer objects in the layer tree contain different values. Without this fill mode, you will see a jump to the final value before the animation begins execution. Other fill modes are also available.

  • The AutoReverses property causes the animation to execute at a specified time and then return to the original value of the animation. We can combine autoreverses with repeatCount to animate back and forth between starting and ending values. Setting the repeat count to an integer for the autogyro animation (for example, 1.0) causes the animation to stop at its starting value. Adding an extra half step (such as a repeat count of 1.5) causes the animation to stop at its end value. Using timeOffset has the group animation property to start some animations at a later time.

Pause and resume the animation of the layer

/** Layer suspends animation */ - (void)pauseLayer (CALayer*)layer {CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; Layer. Speed = 0.0; layer.timeOffset = pausedTime; } /** Layer resumeLayer (CALayer*)layer {CFTimeInterval pausedTime = [Layer timeOffset]; Layer. Speed = 1.0; Layer. The timeOffset = 0.0; Layer. BeginTime = 0.0; CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; layer.beginTime = timeSincePause; }Copy the code

Code and references

Github source address

References:

Core Animation – Official documentation

IOS CALayer Layers (part 1)

Core Animation series CATransaction

Coreanimation (Ultra Detailed Core animation)

IOS animation, principle and practice

Full iOS animation parsing

IOS CoreAnimation Topic — Principle (3) CALayer model layer and display layer