- POP是一个来自于Facebook,在iOS与OSX上通用的极具扩展性的动画引擎。它在基本的静态动画的基础上增加的弹簧动画与衰减动画,使之能创造出更真实更具物理性的交互动画。
- Pop Animation在使用上和Core Animation很相似,都涉及Animation对象以及Animation的载体的概念
- 关于Core Animation的相关详解, 可参考我的上一篇文章Core Animation(核心动画)
- 不同的是Core Animation的载体只能是CALayer,而Pop Animation可以是任意基于NSObject的对象
- POP 使用 Objective-C++ 编写,Objective-C++ 是对 C++ 的扩展

GitHub项目地址

一. POP自我介绍

  • POP 目前由四部分组成:1. Animations;2. Engine;3. Utility;4. WebCore。
  • POP 动画极为流畅,主要在于Enimator 里,POP 通过 CADisplayLink 高达 60 FPS 的特性,打造了一个游戏级的动画引擎。
  • CADisplayLink 是类似 NSTimer 的定时器,不同之处在于,NSTimer 用于我们定义任务的执行周期、资料的更新周期,他的执行受到 CPU 的阻塞影响,而 CADisplayLink 则用于定义画面的重绘、动画的演变,他的执行基于 frames 的间隔。
    • 通过 CADisplayLink,Apple 允许你将 App 的重绘速度设定到和屏幕刷新频率一致,由此你可以获得非常流畅的交互动画,这项技术的应用在游戏中非常常见,著名的 Cocos-2D 也应用了这个重要的技术。
    • WebCore 里包含了一些从 Apple 的开源的网页渲染引擎里拿出的源文件,与 Utility 里的组件一并,提供了 POP 的各项复杂计算的基本支持

二. POP参数介绍

POP默认支持三种动画,但同时也支持自定义动画
  • POPBasicAnimation //基础动画
  • POPSpringAnimation //弹簧动画
  • POPDecayAnimation //衰减动画
  • POPCustomAnimation //自定义动画

1、相关属性介绍

1-1、属性简单介绍

  • POP动画大部分属性和CoreAnimation(核心动画)的含义和用法一样
  • 具体可参考Core Animation(核心动画)
  • 每种动画的特殊属性会在下文中继续介绍

1-2、动画可配置属性

  • CALayer层各属性(比较简单,就不加注释了)
/**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;
  • UIVIew层
/**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;
  • 其他层视图层
/**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;

以上仅仅列出了常用的一些属性,更多控件/更多参考框架里面类
POPAnimatableProperty.h

1-3、POPBasicAnimation可配置的属性与默认值为

POPBasicAnimation *basic = [POPBasicAnimation linearAnimation];
basic.fromValue = @(0);//从0开始    basic.toValue = @(3*60);//180秒后结束
basic.duration = 3*60;//持续3分钟
[lab pop_addAnimation:basic forKey:nil];
let basic1 = POPBasicAnimation(propertyNamed: kPOPLayerPositionX)
basic1?.fromValue = redView.layer.position.x
basic1?.toValue = 300
basic1?.beginTime = CFTimeInterval() + 1.0
redView.pop_add(basic1, forKey: "position.x")

三. POPBasicAnimation基础动画

1. 先看一下效果, 其动画效果如下

2. 示例代码

let basic1 = POPBasicAnimation(propertyNamed: kPOPLayerPositionX)
basic1?.toValue = 300
//开始时间
basic1?.beginTime = CFTimeInterval() + 1.0
redView.pop_add(basic1, forKey: "position.x")

3. 可以看到,添加一个动画最少仅需三步

  • 1)定义一个animation对象,并指定对应的动画属性(kPOPLayerPositionX
  • 2)设置初始值结束值(初始值可以不指定,会默认从当前值开始)
  • 3)添加到想产生动画的对象上

4. Core Animation 和 POP 运行动画对比

  • 由于 POP 是基于定时器定时刷新添加动画的原理,那么如果将动画库运行在主线程上,会由于线程阻塞的问题导致动画效果出现卡顿、不流畅的情况。
  • 更为关键的是,你不能将动画效果放在子线程,因为你不能将对 view 和 layer 的操作放到主线程之外
  • POP 受主线程阻塞的影响很大,在使用过程中,应避免在有可能发生主线程阻塞的情况下使用 POP ,避免制作卡顿的动画效果,产生不好的用户体验

四. POPSpringAnimation弹性动画

1. 属性介绍

  • velocity: 设置动画开始速度
  • springBounciness: 振幅, 可以设置的范围是0-20,默认为4。值越大振动的幅度越大
  • springSpeed: 速度, 可以设置的范围是0-20,默认为12.值越大速度越快,结束的越快
  • dynamicsMass: 质量, 质量越大,动画的速度越慢,振动的幅度越大,结束的越慢
  • dynamicsTension: 拉力 拉力越大,动画的速度越快,结束的越快
  • dynamicsFriction: 摩擦力, 摩擦力越大,动画的速度越慢,振动的幅度越小。

注意: 以上的六个属性中一般只会设置springBouncinessspringSpeed, 如有特殊需求才会设置其他属性

2. 代码示例

let spring = POPSpringAnimation(propertyNamed: kPOPViewScaleXY)
//注意: 这里改变的是x和y的比例,参数赋值也要传两个; 若只需要其中一个,则可设置
//`spring?.fromValue = 0.4`即可
spring?.fromValue = CGSize(width: 0.3, height: 0.3)
spring?.toValue = CGSize(width: 2, height: 2)
spring?.springSpeed = 5
spring?.springBounciness = 15
lightBlue.pop_add(spring, forKey: "scale")

五. POPDecayAnimation

  • POPDecayAnimation提供一个过阻尼效果(其实Spring是一种欠阻尼效果)可以实现类似UIScrollView的滑动衰减效果(是的你可以靠它来自己实现一个UIScrollView

属性介绍
- deceleration (负加速度, 衰减系数(越小则衰减得越快)) 是一个你会很少用到的值,默认是就是我们地球的 0.998,如果你开发APP给火星人用,那么这个值你使用 0.376 会更合适
- velocity 也是必须和你操作的属性有相同的结构,如果你操作的是 bounds, 传CGRect类型;如果 velocity 是负值,那么就会反向递减

代码示例

let decay = POPDecayAnimation(propertyNamed: kPOPViewSize)
decay?.velocity = CGSize(width: 300, height: pictureBtn.frame.height)
//延迟1秒后执行
decay?.beginTime = CACurrentMediaTime() + 1.0
pictureBtn.pop_add(decay, forKey: "size")

六. 自定义属性

POP默认支持的三种动画都继承自POPPropertyAnimation, POPPropertyAnimation中定义了一个叫property的属性(之前没有用到它是因为POP根据不同的默认动画属性帮你生成了默认的property这个属性则是用来驱动POP的动画效果中的重要一环

1. 实力模块

if let proper = POPAnimatableProperty.property(withName: "prop", initializer: { (prop) inguard let prop = prop else { return }//readprop.readBlock = { (obj, values) in}//writeprop.writeBlock = {(obj, values) in}prop.threshold = 0.01}) as? POPAnimatableProperty {anim.property = proper
}

2. 属性介绍

其组成就是一个readBlock一个writeBlock和一个threashold
- readBlock告诉POP当前的属性值
- writeBlock中修改变化后的属性值
- threashold决定了动画变化间隔的阈值 值越大writeBlock的调用次数越少

POPAnimatableProperty其实是POP中一个比较重要的东西 像上面提到的POP自带的动画属性 查看源代码可以看到也只是POP自动帮你设置好了POPAnimatableProperty而已 其作用就是当动画的某个时间片被触发时 告诉系统如何根据当前时间片做出变化

还是以一个实际的例子来说明如何使用自定义属性 比如我们要实现一个像系统的时钟APP里秒表计时的一个效果

3. 完整代码示例

if let proper = POPAnimatableProperty.property(withName: "prop", initializer: { (prop) inguard let prop = prop else { return }//readprop.readBlock = { (obj, values) inguard let array = values else { return }print(array[0])}//writeprop.writeBlock = {(obj, values) inguard 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() {//秒表用线性的时间函数初始化popBasic.property = properpopBasic.fromValue = 0 //从0开始popBasic.toValue = 18  //到18秒popBasic.duration = 18 //持续18秒popBasic.beginTime = CACurrentMediaTime() + 2 //延迟2秒开始pictureBtn.pop_add(popBasic, forKey: "linear")}
}

4. 注意:

  • 在Swift4.0版本(4.0之前版本未知)中,初始化出来的对象都是可选类型
  • POP官方的建议是添加if条件判断,详情可到GitHub上查看示例
  • 正如上段代码所示: 闭包中涉及的可选类型都添加了guard判断

七. 类似微博中间发布按钮弹出动画

先看一下效果吧

动画分为两个部分

  • 中间六个按钮依次执行动画弹出
  • 上面标题图片最后动画落下

下面来看一下部分的核心代码

1. 六个按钮的弹出和消失动画
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/Ylet row = i / maxColslet col = i % maxColslet buttonX = btnStsrtX + CGFloat(col) * (xMargin + buttonW)let buttonEndY = btnStartY + CGFloat(row) * buttonHlet buttonStartY = buttonEndY - kScreenHeight//按钮动画let 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 = kSpringFactorpopSpring?.springSpeed = kSpringFactorpopSpring?.beginTime = CACurrentMediaTime() + kAnimationDelay * Double(i)button.pop_add(popSpring, forKey: "spring")
}
2. 最上部分标语的弹出和消失
//z执行动画
let 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, finished in//所有动画执行完毕,回复View点击事件kRootView?.isUserInteractionEnabled = trueself.isUserInteractionEnabled = true
}
topImage.pop_add(imagePOP, forKey: nil)

以上是类似微博动画的部分核心代码, 具体代码详见GitHub项目, 喜欢请star

github项目介绍

  • 折叠图片
  • 音量震动条
  • 活动指示器
  • 微博动画
  • 倒计时-计时器
  • 类似QQ信息条数的粘性动画
  • 类似雷达-水波纹动画

注: 项目持续更新中……

iOS之POP动画使用和实战相关推荐

  1. iOS动画——弹窗动画(pop动画)

    用pop动画简单实现弹窗的缩放和渐变,感觉这个动画常用,就写一下博客 pop动画是Facebook推出的动画引擎,请自行到GitHub上搜索下载拖拽导入xcode项目中. 更多pop动画使用和原理可网 ...

  2. Facebook POP 动画框架 进阶指南

    http://www.cocoachina.com/industry/20140704/9034.html http://www.cocoachina.com/ios/20140508/8352.ht ...

  3. [iOS]调和 pop 手势导致 AVPlayer 播放卡顿

    作者 NewPan 关注 2017.07.15 14:24* 字数 3110 阅读 749评论 8喜欢 17 声明:我为这个框架写了四篇文章: 第一篇:[iOS]UINavigationControl ...

  4. iOS CAReplicatorLayer 简单动画

    代码地址如下: http://www.demodashi.com/demo/11601.html 写在最前面,最近在看学习的时候,偶然间发现一个没有用过的Layer,于是抽空研究了下,本来应该能提前记 ...

  5. iOS进阶4 -- 动画总结

    1.基础:逐帧 与 关键帧 逐帧动画: 类似于手绘翻页方式,我们可以将这个水杯在每帧画面中的位置一一找出来,这样实现动画的方式就叫作 逐帧动画,我们需要处理动画中的每一帧. 我们一般在计算机上用 FP ...

  6. iOS网络资源(动画)

    Core Animation笔记,基本的使用方法 - Core Animation笔记,基本的使用方法:1.基本动画, 2.多步动画,3.沿路径的动画,4.时间函数,5.动画组. awesome-io ...

  7. iOS学习——核心动画之Layer基础

    iOS学习--核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...

  8. IOS之Swift5.x开发通讯录实战

    IOS之Swift5.x开发通讯录实战 swift基础知识的使用. 闭包,连线 ,强制解包 页面的传值,模型的构建.自定义Cell等知识的使用. // // LJPerson.swift // 03- ...

  9. ios开发基础之通讯录系统实战-20

    ios开发基础之通讯录系统实战 基础知识 OC 基础 segue 的使用.delegate 代理的使用 自定义代理.面向对象思想 沙盒容器的数据持久化方案, controller 之间的跳转 ,登录方 ...

最新文章

  1. JSPServlet(1)
  2. xman的思维导图快捷键_Xmind:ZEN思维导图有哪些使用技巧,最实用的快捷键是什么?...
  3. [转]Muilti-touch 双指缩放的实现探索
  4. vue 代理设置 访问图片_详解Vue源码之数据的代理访问
  5. 计算机科学与技术专题,专题四 计算机科学与应用技术.ppt
  6. 在浏览器中运行java applet
  7. 2019快手内容报告重磅发布:日活突破3亿 点赞量超3500亿
  8. 基于jQuery开发的javascript模板引擎-jTemplates
  9. ionic2——环境配置篇
  10. java8 function 多线程安全_Java8新特性_传统时间格式化的线程安全问题
  11. 简单实用的 Ubuntu 快捷键
  12. 看微软“第四代模块化数据中心”宣传片之后的思考
  13. orcad16.3下载
  14. Apache启动失败,请检查相关配置。√MySQL5.1已启动。
  15. 投影仪幕布增益_别再说幕布是花瓶 投影幕布的作用原来这么大
  16. ks108x芯片使用体会
  17. 凌晨!科比因坠机离世, 球迷泪崩:凌晨4点,我的青春没了
  18. Eclipse连接Hadoop集群(详细版)
  19. 2020_ACL_A Transformer-based joint-encoding for Emotion Recognition and Sentiment Analysis
  20. python图像轮廓识别_Python+OpenCV图像处理(十六)—— 轮廓发现

热门文章

  1. 1468 - 平方矩阵 Python
  2. Ubuntu全新安装firefox最新版本
  3. Sping Mvc 学习笔记(一)
  4. html给标题设置背景,怎么在html中设置一级标题背景
  5. VMware打开VMDK格式文件
  6. 王者荣耀微信转qq服务器,王者荣耀转区qq转微信可以吗 qq转区微信可以吗
  7. 疑问代词which/what/who的用法
  8. 游戏化方式学习Git指令
  9. 地图匹配实例-几何匹配
  10. MATLAB实现2ASK,2PSK,2FSK