• POP is a very extensible animation engine from Facebook, available on iOS and OSX. It adds spring animation and attenuation animation on the basis of basic static animation, so that it can create a more real and more physical interactive animation.
  • Pop AnimationAnd in useCore AnimationVery similar, both involvedAnimationObjects, andAnimationThe concept of carrier
  • aboutCore AnimationPlease refer to my last article for more detailsCore Animation
  • The difference isCore AnimationThe carrier can only beCALayerAnd thePop AnimationCan be arbitrary basedNSObjectThe object of
  • POPuseObjective-C++Write,Objective-C++Is theC++The extension of the

GitHub project address

POP Introduce yourself

  • POP currently consists of four parts: 1. Animations; 2. Engine; 3. The Utility; 4. WebCore.
  • POP animation is extremely smooth, mainly in Enimator. POP has built a game-level animation engine with CADisplayLink up to 60 FPS.
  • CADisplayLink is a timer similar to NSTimer. The difference is that NSTimer is used to define the execution period of tasks and the update period of data. Its execution is affected by CPU blocking, while CADisplayLink is used to define the redrawing of pictures and the evolution of animation. His execution is based on the interval between frames.
  • With CADisplayLink, Apple allows you to redraw your App at the same rate as the screen refresh, so you can get very smooth interactive animations. This technology is very common in games, and the famous CocoS-2D also uses this important technology.
  • WebCore contains some source files from Apple’s open source web rendering engine, along with components from The Utility, to provide basic support for POP’s complex calculations

2. POP parameter introduction

POP supports three animations by default, but also supports custom animations
  • POPBasicAnimation// Basic animation
  • POPSpringAnimation// Spring animation
  • POPDecayAnimation// Decrement animation
  • POPCustomAnimation// Custom animation

1. Introduction of related attributes

1-1. Brief introduction to attributes

  • Most of the properties of POP animation have the same meaning and usage as CoreAnimation
  • For details, see Core Animation.
  • The special properties of each animation are described below

1-2. Configurable properties for animation

  • Properties of the CALayer layer (simple, uncommented)
/** Common CALayer property names. */
extern NSString * const kPOPLayerBackgroundColor;
extern NSString * const kPOPLayerBounds;
extern NSString * const kPOPLayerCornerRadius;
extern NSString * const kPOPLayerBorderWidth;
extern NSString * const kPOPLayerBorderColor;
extern NSString * const kPOPLayerOpacity;
extern NSString * const kPOPLayerPosition;
extern NSString * const kPOPLayerPositionX;
extern NSString * const kPOPLayerPositionY;
extern NSString * const kPOPLayerRotation;
extern NSString * const kPOPLayerRotationX;
extern NSString * const kPOPLayerRotationY;
extern NSString * const kPOPLayerScaleX;
extern NSString * const kPOPLayerScaleXY;
extern NSString * const kPOPLayerScaleY;
extern NSString * const kPOPLayerSize;
extern NSString * const kPOPLayerSubscaleXY;
extern NSString * const kPOPLayerSubtranslationX;
extern NSString * const kPOPLayerSubtranslationXY;
extern NSString * const kPOPLayerSubtranslationY;
extern NSString * const kPOPLayerSubtranslationZ;
extern NSString * const kPOPLayerTranslationX;
extern NSString * const kPOPLayerTranslationXY;
extern NSString * const kPOPLayerTranslationY;
extern NSString * const kPOPLayerTranslationZ;
extern NSString * const kPOPLayerZPosition;
extern NSString * const kPOPLayerShadowColor;
extern NSString * const kPOPLayerShadowOffset;
extern NSString * const kPOPLayerShadowOpacity;
extern NSString * const kPOPLayerShadowRadius;

Copy the code
  • UIVIew layer
/**
 Common UIView property names.
 */
extern NSString * const kPOPViewAlpha;
extern NSString * const kPOPViewBackgroundColor;
extern NSString * const kPOPViewBounds;
extern NSString * const kPOPViewCenter;
extern NSString * const kPOPViewFrame;
extern NSString * const kPOPViewScaleX;
extern NSString * const kPOPViewScaleXY;
extern NSString * const kPOPViewScaleY;
extern NSString * const kPOPViewSize;
extern NSString * const kPOPViewTintColor;

Copy the code
  • Other layers view layers
/** Common UINavigationBar property names. */
extern NSString * const kPOPNavigationBarBarTintColor;

/** Common UIToolbar property names. */
extern NSString * const kPOPToolbarBarTintColor;

/** Common UITabBar property names. */
extern NSString * const kPOPTabBarBarTintColor;

/** Common UILabel property names. */
extern NSString * const kPOPLabelTextColor;

Copy the code

This is just a list of common properties. More controls/more reference frames popAnimatableProperty.h

1-3. The configurable properties and default values of POPBasicAnimation are

POPBasicAnimation *basic = [POPBasicAnimation linearAnimation];
basic.fromValue = @(0);ToValue = @(3*60); // End after 180 seconds
basic.duration = 3*60;// Lasts 3 minutes
[lab pop_addAnimation:basic forKey:nil];

Copy the code
let basic1 = POPBasicAnimation(propertyNamed: kPOPLayerPositionX) basic1? .fromValue = redView.layer.position.x basic1?.toValue =300basic1? .beginTime =CFTimeInterval() + 1.0
redView.pop_add(basic1, forKey: "position.x")

Copy the code

POPBasicAnimation

1. Take a look at the effects. The animation looks like this

2. sample code

let basic1 = POPBasicAnimation(propertyNamed: kPOPLayerPositionX) basic1? .toValue =300
// Start timebasic1? .beginTime =CFTimeInterval() + 1.0
redView.pop_add(basic1, forKey: "position.x")
Copy the code

3. As you can see, adding an animation takes at least three steps

  • 1) Define oneanimationObject and specify the corresponding animation property (kPOPLayerPositionX)
  • 2) Set the initial end value (the initial value can not be specified, but will default to the current value)
  • 3) Add to the object you want to animate

4. Core Animation and POP run Animation comparison

  • Since POP is based on the principle of adding animation with timer refresh, if the animation library is run on the main thread, the animation effect will be stuttering and not smooth due to the problem of thread blocking.
  • More importantly, you can’t put animations on child threads, because you can’t put operations on view and Layer outside the main thread
  • POP is greatly affected by main thread blocking. During the use of POP, avoid using POP when main thread blocking is likely to occur, to avoid the production of stuttering animation effect, resulting in bad user experience

B: POPSpringAnimation

1. Attributes

  • velocity: Sets the animation start speed
  • springBounciness: amplitude, which can be set from 0 to 20. The default is 4. The greater the value, the greater the amplitude of the vibration
  • springSpeed: Speed. The value ranges from 0 to 20. The default value is 12
  • dynamicsMass: mass, the greater the mass, the slower the animation, the greater the vibration, the slower the end
  • dynamicsTensionThe higher the pull, the faster the animation will go and the faster it will end
  • dynamicsFriction: friction, the greater the friction, the slower the animation speed, the smaller the vibration amplitude.

Note: Generally, only springBounciness and springSpeed are set for the above six properties. Other properties are set only if there are special requirements

2. Code examples

letSpring = POPSpringAnimation(propertyNamed: kPOPViewScaleXY) // If only one of them is needed, set // 'spring? .tovalue = CGSize(width: 2, height: 0.3).tovalue = CGSize(width: 2, height: 0.3) 2) spring?.springSpeed = 5 spring?.springBounciness = 15 lightBlue.pop_add(spring,forKey: "scale")

Copy the code

Five POPDecayAnimation.

  • POPDecayAnimationProvides an overdamping effect (actuallySpringIs an underdamped effect) can be achieved similarlyUIScrollViewSlide decay effect (yes you can make one yourselfUIScrollView)

Attribute is introduced

  • deceleration(Negative acceleration, decay coefficient (the smaller it is, the faster it decays)) is a value you will rarely use. The default value is 0.998 for Earth, and if you are developing an APP for Martians, this value will be more appropriate if you use 0.376
  • velocityIt must also have the same structure as the property you operate on. If you operate on bounds, pass the CGRect type. If velocity is negative, it decreases in reverse

Code sample

letdecay = POPDecayAnimation(propertyNamed: kPOPViewSize) decay? .velocity = CGSize(width: 300, height: BeginTime = CACurrentMediaTime() + 1.0 picturebtn.pop_add (decay, picturebtn.frame.forKey: "size")

Copy the code

Custom attributes

The three types of animation supported by POP by default all inherit from POPPropertyAnimation, POPPropertyAnimation defines a property called Property (I didn’t use it before because POP generates the default property for you based on the different default animation properties) and this property is an important part of the animation that drives POP

1. Strength module

if let proper = POPAnimatableProperty.property(withName: "prop", initializer: { (prop) in
    guard let prop = prop else { return }
    //read
    prop.readBlock = { (obj, values) in
                
    }
            
    //write
    prop.writeBlock = {(obj, values) in
                
    }
    prop.threshold = 0.01
            
}) as? POPAnimatableProperty {
    anim.property = proper
}
Copy the code

2. Attributes

It consists of a readBlock, a writeBlock and a Threashold

  • readBlockTells POP the current property value
  • writeBlockTo modify the changed attribute value
  • threasholdDetermines the larger the threshold value of the animation change intervalwriteBlockThe fewer times you call

POPAnimatableProperty is actually one of the most important things in POP like the animation property in POP that I mentioned above and if you look at the source code you can see that it’s just POP that automatically sets the POPAnimatableProperty for you and what it does is when the slice of the animation is triggered at some point in time Tell the system how to make changes based on the current time slice

Or is it a practical example of how to use custom properties like we want to implement an effect like a stopwatch in the system clock APP

3. Complete code sample

if let proper = POPAnimatableProperty.property(withName: "prop", initializer: { (prop) in
    guard let prop = prop else { return }
    //read
    prop.readBlock = { (obj, values) in
        guard let array = values else { return }
        print(array[0])}//write
    prop.writeBlock = {(obj, values) in
        guard let button = obj as? UIButton, let array = values else { return }
        let value = array[0]
        button.setTitle(String(format: "%02d:%02d:%02d", Int(value / 60), Int(value.truncatingRemainder(dividingBy: 60)), Int((value * 100).truncatingRemainder(dividingBy: 100))), for: .normal)
    }
    prop.threshold = 0.01
    
}) as? POPAnimatableProperty {
    if let popBasic = POPBasicAnimation.linear() {
        // The stopwatch is initialized with a linear time function
        popBasic.property = proper
        popBasic.fromValue = 0 // Start at 0
        popBasic.toValue = 18  / / to 18 seconds
        popBasic.duration = 18 // Lasts 18 seconds
        popBasic.beginTime = CACurrentMediaTime() + 2 // Delay start by 2 seconds
        pictureBtn.pop_add(popBasic, forKey: "linear")}}Copy the code

4. Note:

  • In Swift4.0 (unknown prior to 4.0), initialized objects are optional types
  • POPThe official recommendation is to addifFor details, see GitHub for an example
  • As shown in the previous code: The optional types involved in closures have been addedguardjudge

Vii. Similar to the pop-up animation of the release button in the middle of weibo

Let’s take a look at the effect

The animation is divided into two parts

  • The middle six buttons in turn perform animation pop-up
  • The title picture above falls at the end of the animation

Let’s take a look at some of the core code

1. Six button pop up and disappear animation
for i in 0..<titles.count {
    let button = BaseButton()
    button.setTitle(titles[i], for: .normal)
    button.setImage(UIImage(named: images[i]), for: .normal)
    button.addTarget(self, action: #selector(buttonClick(button:)), for: .touchUpInside)
    addSubview(button)
    
    //计算X/Y
    let row = i / maxCols
    let col = i % maxCols
    let buttonX = btnStsrtX + CGFloat(col) * (xMargin + buttonW)
    let buttonEndY = btnStartY + CGFloat(row) * buttonH
    let buttonStartY = buttonEndY - kScreenHeight
    
    // Button animationlet popSpring = POPSpringAnimation(propertyNamed: kPOPViewFrame) popSpring? .fromValue =CGRect(x: buttonX, y: buttonStartY, width: buttonW, height: buttonH) popSpring? .toValue =CGRect(x: buttonX, y: buttonEndY, width: buttonW, height: buttonH) popSpring? .springBounciness = kSpringFactor popSpring? .springSpeed = kSpringFactor popSpring? .beginTime =CACurrentMediaTime() + kAnimationDelay * Double(i)
    button.pop_add(popSpring, forKey: "spring")}Copy the code
2. Pop-up and disappearance of the top part of the slogan
//z executes the animationlet imagePOP = POPSpringAnimation(propertyNamed: kPOPViewCenter) imagePOP? .fromValue =CGPoint(x: kScreenWidth * 0.5, y: 0.2* kScreenHeight - kScreenHeight) imagePOP? .toValue =CGPoint(x: kScreenWidth * 0.5, y: 0.2* kScreenHeight) imagePOP? .springSpeed = kSpringFactor imagePOP? .springBounciness = kSpringFactor imagePOP? .beginTime =CACurrentMediaTime() + Double(btnCount) * kAnimationDelay imagePOP? .completionBlock = { popAnim, finishedin
    // After all animations are executed, reply to the View click eventkRootView? .isUserInteractionEnabled =true
    self.isUserInteractionEnabled = true
}
topImage.pop_add(imagePOP, forKey: nil)

Copy the code

The above is part of the core code similar to weibo animation. Please refer to the GitHub project for the specific code

Github project introduction

  • Folding pictures
  • Volume vibrator
  • Activity indicator
  • Weibo animation
  • Countdown – timer
  • Similar to QQ message number of sticky animation
  • Similar to radar – water ripple animation

Note: the project continues to be updated at……