美文网首页
iOS-Facebook-Pop-动效库的使用教程(Swift版

iOS-Facebook-Pop-动效库的使用教程(Swift版

作者: 老坛泡菜 | 来源:发表于2020-06-01 23:54 被阅读0次

简介:

好久没更新文章了,今天讲的是Facebook出的一款动效库Facebook-Pop。(部分内容摘自互联网,文章最后附有demo地址,有什么不对的地方,欢迎大家指正出来,大神勿喷,嘿嘿)

Pop是一个动画引擎,用以扩展iOS、OSX的动画类型。相较于iOS、OSX中的基本动画效果,Pop扩展后支持弹簧动画效果与衰减动画效果,你可以用Pop动画引擎来构建出真实的物理交互效果。它的API与Core Animation的API非常类似,使用起来非常容易。Pop动画引擎已经经过了良好的测试,Facebook在 Paper 应用中进行了大量使用。
官方Git地址:https://github.com/facebook/pop

iOS原生的Core Animation框架只提供了linear, ease-in, ease-out和ease-in-ease-out等4种静态动画:



而Pop在Core Animation基础上增加Spring、Decay和Custom 3种动态动画效果:



Spring(弹性)和Decay(衰减)可以让动画变得更灵动,而Custom这更为强大,可以给任何NSObject对象属性添加动画效果(待会有例子介绍)。

所以今天主要讲的就是4个动画效果

  • POPBasicAnimation //基础动画
  • POPSpringAnimation //弹性动画
  • POPDecayAnimation //衰减动画
  • POPCustomAnimation //自定义动画

使用

POPBasicAnimation

  • POPBasicAnimation使用最广泛 提供固定时间间隔的动画(如淡入淡出效果)
    let animation = POPBasicAnimation(propertyNamed: kPOPLayerPositionX)
    animation.toValue = NSValue(CGPoint: CGPointMake(100, 200))
    animation.duration = 2
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
    view.layer.pop_addAnimation(animation, forKey: "positionX")
    其实只有3个步骤就能创建一个动画
    1.创建对应的动画类型,这里我使用的是kPOPLayerPositionX来控制view的位置
    2.设置动画的属性
    toValue设置动画的最终值(对应的还有fromValue是设置动画的起始值,不写默认为当前值)
    duration设置动画时长
    timingFunction是系统预设的动画类型有以下5种:
kCAMediaTimingFunctionLinear            线性,即匀速
kCAMediaTimingFunctionEaseIn            先慢后快
kCAMediaTimingFunctionEaseOut           先快后慢
kCAMediaTimingFunctionEaseInEaseOut     先慢后快再慢
kCAMediaTimingFunctionDefault           实际效果是动画中间比较快

这里使用的是EaseIn(先慢后快)
3.最后只需把动画add到对应视图的layer就完成,设置了key可以方便删除和修改动画,例如:
[layer pop_removeAnimationForKey:@"positionX"];

POPSpringAnimation

  • POPSpringAnimation也许是大多数人使用POP的理由 其提供一个类似弹簧一般的动画效果(炫酷!)
let animation = POPSpringAnimation(propertyNamed: kPOPLayerScaleXY)
animation!.toValue = NSValue(CGSize: CGSizeMake(5, 5))
animation!.springBounciness = 10 //[0-20] 弹力 越大则震动幅度越大
animation!.springSpeed = 20 //[0-20] 速度 越大则动画结束越快
//以下3个与物理力学模拟相关,没特殊需求不建议使用
//        animation.dynamicsFriction = 0 //拉力
//        animation.dynamicsFriction = 0 //摩擦
//        animation.dynamicsMass = 0 //质量
view.layer.pop_addAnimation(animation, forKey: "scaleXY")

POPSpringAnimation是没有duration字段的 其动画持续时间由以上几个参数决定,简单的几个步骤就能实现非常炫酷灵动的效果了

POPDecayAnimation

  • POPDecayAnimation提供一个过阻尼效果(其实Spring是一种欠阻尼效果) 可以实现类似UIScrollView的滑动衰减效果(是的 你可以靠它来自己实现一个UIScrollView)
let animation = POPDecayAnimation(propertyNamed: kPOPLayerPositionX)
        
 animation.velocity = 200 //速度
 animation.deceleration = 0.998 // 衰减系数(越小则衰减得越快)
        
 //目的状态toValue是通过velocity和deceleration计算,动态得到
        
 view.layer.pop_addAnimation(animation, forKey: "decayPosition")

这是一个很简单的移动例子,当然强大的POP不止这些属性,在POPAnimatableProperty文件中还有很多可操作的属性,并且维护者还在不断增加:

/**
 Common CALayer property names.
 */
public let kPOPLayerBackgroundColor: String
public let kPOPLayerBounds: String
public let kPOPLayerCornerRadius: String
public let kPOPLayerBorderWidth: String
public let kPOPLayerBorderColor: String
public let kPOPLayerOpacity: String
public let kPOPLayerPosition: String
public let kPOPLayerPositionX: String
public let kPOPLayerPositionY: String
public let kPOPLayerRotation: String
public let kPOPLayerRotationX: String
public let kPOPLayerRotationY: String
public let kPOPLayerScaleX: String
public let kPOPLayerScaleXY: String
public let kPOPLayerScaleY: String
public let kPOPLayerSize: String
public let kPOPLayerSubscaleXY: String
public let kPOPLayerSubtranslationX: String
public let kPOPLayerSubtranslationXY: String
public let kPOPLayerSubtranslationY: String
public let kPOPLayerSubtranslationZ: String
public let kPOPLayerTranslationX: String
public let kPOPLayerTranslationXY: String
public let kPOPLayerTranslationY: String
public let kPOPLayerTranslationZ: String
public let kPOPLayerZPosition: String
public let kPOPLayerShadowColor: String
public let kPOPLayerShadowOffset: String
public let kPOPLayerShadowOpacity: String
public let kPOPLayerShadowRadius: String
/**
 Common CAShapeLayer property names.
 */
public let kPOPShapeLayerStrokeStart: String
public let kPOPShapeLayerStrokeEnd: String
public let kPOPShapeLayerStrokeColor: String
public let kPOPShapeLayerFillColor: String
public let kPOPShapeLayerLineWidth: String
public let kPOPShapeLayerLineDashPhase: String
/**
 Common NSLayoutConstraint property names.
 */
public let kPOPLayoutConstraintConstant: String
/**
 Common UIView property names.
 */
public let kPOPViewAlpha: String
public let kPOPViewBackgroundColor: String
public let kPOPViewBounds: String
public let kPOPViewCenter: String
public let kPOPViewFrame: String
public let kPOPViewScaleX: String
public let kPOPViewScaleXY: String
public let kPOPViewScaleY: String
public let kPOPViewSize: String
public let kPOPViewTintColor: String
/**
 Common UIScrollView property names.
 */
public let kPOPScrollViewContentOffset: String
public let kPOPScrollViewContentSize: String
public let kPOPScrollViewZoomScale: String
public let kPOPScrollViewContentInset: String
public let kPOPScrollViewScrollIndicatorInsets: String
/**
 Common UITableView property names.
 */
public let kPOPTableViewContentOffset: String
public let kPOPTableViewContentSize: String
/**
 Common UICollectionView property names.
 */
public let kPOPCollectionViewContentOffset: String
public let kPOPCollectionViewContentSize: String
/**
 Common UINavigationBar property names.
 */
public let kPOPNavigationBarBarTintColor: String
/**
 Common UIToolbar property names.
 */
public let kPOPToolbarBarTintColor: String
/**
 Common UITabBar property names.
 */
public let kPOPTabBarBarTintColor: String
/**
 Common UILabel property names.
 */
public let kPOPLabelTextColor: String

什么?你说这里面没有你需要的,别着急POP还有更强大的自定义属性功能

自定义属性

  • POP默认支持的三种动画都继承自POPPropertyAnimation POPPropertyAnimation中定义了一个叫property的属性( 之前没有用到它是因为POP根据不同的默认动画属性帮你生成了默认的property) 而这个property则是用来驱动POP的动画效果中的重要一环
POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"prop" initializer:^(POPMutableAnimatableProperty *prop) {
    // read value
    prop.readBlock = ^(id obj, CGFloat values[]) {
        
    };
    // write value
    prop.writeBlock = ^(id obj, const CGFloat values[]) {
    
    };
    // dynamics threshold
    prop.threshold = 0.01;
}];

其组成就是一个readBlock一个writeBlock和一个threashold

readBlock告诉POP当前的属性值
writeBlock中修改变化后的属性值
threashold决定了动画变化间隔的阈值 值越大writeBlock的调用次数越少
POPAnimatableProperty其实是POP中一个比较重要的东西 像上面提到的POP自带的动画属性 查看源代码可以看到也只是POP自动帮你设置好了POPAnimatableProperty而已 其作用就是当动画的某个时间片被触发时 告诉系统如何根据当前时间片做出变化

直接上案例,我们要实现一个像系统的时钟APP里秒表计时的一个效果

testLabel = UILabel(frame: CGRectMake(0,0,100,50))
testLabel.center = view.center
view.addSubview(testLabel!)
        
let prop = POPAnimatableProperty.propertyWithName("Custom") { (prop) in
    prop.writeBlock = {(obj, value) -> Void in
        let lable = obj as! UILabel
        lable.text = String.init(format: "%02d:%02d:%02d", Int(value[0]/60),Int(value[0]%60),Int((value[0]*100)%100))
    }
}
let anBasic = POPBasicAnimation.linearAnimation()
anBasic.property = prop as! POPAnimatableProperty
anBasic.fromValue = 0
anBasic.toValue = 3*60
anBasic.duration = 3*60
testLabel!.pop_addAnimation(anBasic, forKey: "Custom")

效果如下:


从这个例子中有没有新的启发呢,POP可以做的事情远比CoreAnimation要多,它的强大毋庸置疑。


Demo地址:https://github.com/yueyeqi/Facebook-PopExample


小结

其实只需要熟练掌握POP自带的三种动画 即可完成大部分的动画效果 如果实在是无法满足你的需求的话 自定义动画也基本可以满足你的要求 可以说POP化繁为简的出现 极大的方便了我们这些苦逼的coder 本文主要只介绍了最基本的使用方法和思路,更多的知识和效果还待大家深入了解 完。

如果本文对你有用,非常感谢能给个赞噢~~

  • 推荐 :

iOS进阶技术群:1080059793,讨论技术, 大家一起交流学习成长

申请即送: 各类资料免费领取,包括 BAT大厂面试题、数据结构、底层进阶、图形视觉、音视频、架构设计、逆向安防、RxSwift、flutter


相关文章

网友评论

      本文标题:iOS-Facebook-Pop-动效库的使用教程(Swift版

      本文链接:https://www.haomeiwen.com/subject/ibxyzhtx.html