学习使用炫酷的 Facebook Pop (一)

学习一下facebook pop framework。
这是一个非常出名的iOS animation框架,据说本来是苹果不开发给开发者的。但是后来不知道怎么搞的,突然被公开出来。故事看了几篇,也什么亮点,自动忘记了。focus到这个开源框架。

到github上面一搜pop animation,星星最多的那个就是facebook pop,下面还有很多大牛小牛们写的代码,但是由于我这台电脑的cocoapod有点问题,git上面好多代码都跑不了,也没有办法去自己建立一个pod工程(急需解决一下)。幸好有一个写得很好的,一个名字是sh。。(忘记了)的大牛写的popping-master,代码的MVC结构写得特别好,很便于做demo测试。我就直接用了。

在看了很多别人的代码以及官方的介绍,再结合一些有用的博客之后,算是了解了这个framework的大概。为了记录核心的思想,把一个cocoa china上面找到的比较好的介绍转到这里。


【转】facebook pop 使用指南
一.基本概念
 
在计算机的世界里面,其实并不存在绝对连续的动画,你所看到的屏幕上的动画本质上都是离散的,只是在一秒的时间里面离散的帧多到一定的数量人眼就觉得是连续的了,在iOS中,最大的帧率是60帧每秒。 iOS提供了Core Animation框架,只需要开发者提供关键帧信息,比如提供某个animatable属性终点的关键帧信息,然后中间的值则通过一定的算法进行插值计算,从而实现补间动画。 Core Aniamtion中进行插值计算所依赖的时间曲线由CAMediaTimingFunction提供。 Pop Animation在使用上和Core Animation很相似,都涉及Animation对象以及Animation的载体的概念,不同的是Core Animation的载体只能是CALayer,而Pop Animation可以是任意基于NSObject的对象。当然大多数情况Animation都是界面上显示的可视的效果,所以动画执行的载体一般都直接或者间接是UIView或者CALayer。但是如果你只是想研究Pop Animation的变化曲线,你也完全可以将其应用于一个普通的数据对象,比如下面这个对象:
 
 
  1. @interface AnimatableModel : NSObject 
    @property (nonatomic,assign) CGFloat animatableValue; 
    @end 
     
    #import "AnimatableModel.h" 
    @implementation AnimatableModel 
    - (void)setAnimatableValue:(CGFloat)animatableValue{ 
      _animatableValue = animatableValue; 
      NSLog(@"%f",animatableValue); 
    } 
     
    @end 


 
此对象只有一个CGFloat类型的属性,非常简单,这里在AnimatableModel对象上运行几种Pop Animation进行测试,以便统计animatableValue的变化曲线。
 
由于此对象的属性不在Pop Property的标准属性中,所以需要创建一个POPAnimatableProperty,
 
 
  1. POPAnimatableProperty *animatableProperty = [POPAnimatableProperty propertyWithName:@"com.geeklu.animatableValue" initializer:^(POPMutableAnimatableProperty *prop) { 
      prop.writeBlock = ^(id obj, const CGFloat values[]) { 
          [obj setAnimatableValue:values[0]]; 
      }; 
      prop.readBlock = ^(id obj, CGFloat values[]) { 
          values[0] = [obj animatableValue]; 
      }; 
    ; 

PopBasicAniamtion With EaseOut TimingFunction
 
 
  1. POPBasicAnimation *animation = [POPBasicAnimation animation]; 
    animation.property = animatableProperty; 
    animation.fromValue = [NSNumber numberWithFloat:0]; 
    animation.toValue = [NSNumber numberWithFloat:100]; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
    animation.duration = 1.5; 
     
    _animatableModel = [[AnimatableModel alloc] init]; 
    [_animatableModel pop_addAnimation:animation forKey:@"easeOut"]; 
 
从上图可以看到,动画开始的时候变化速率较快,到结束的时候就很慢了,这就是所谓的Ease Out效果。

PopSpringAniamtion
 
 
  1. POPSpringAnimation *animation = [POPSpringAnimation animation]; 
    animation.property = animatableProperty; 
    animation.fromValue = [NSNumber numberWithFloat:0]; 
    animation.toValue = [NSNumber numberWithFloat:100]; 
    animation.dynamicsMass = 5; 
     
    _animatableModel = [[AnimatableModel alloc] init]; 
    [_animatableModel pop_addAnimation:animation forKey:@"spring"]; 
 
 一开始快速向终点方向靠近,然后会在终点附近来回摆动,摆动幅度逐渐变弱,最后在终点停止。

 
通过上面的两个属性值变化的曲线你可以很好的理解动画的类型和属性的变化曲线之前的关联了。
 
二.Pop Animation的使用
 
这里就讲讲Pop Aniamtion自带的几种动画的使用。 Pop Animation自带的动画都是基于POPPropertyAnimation的,POPPropertyAnimation有个很重要的部分就是 POPAnimatableProperty,用来描述animatable的属性。上一节中就看到了如何来创建一个POPAnimatableProperty对象,在初始化的时候,需要在初始化的block中设置writeBlock和readBlock
 
 
  1. void (^readBlock)(id obj, CGFloat values[]) 
  2. void (^writeBlock)(id obj, const CGFloat values[]) 
这两个block都是留给动画引擎来使用的,前者用于向目标属性写值,使用者需要做的就是从values中提取数据设置给obj;后者用于读取,也就是从objc中读取放到values中。values[] 最多支持4个数据,也就是说Pop Aniamtion属性数值的维度最大支持4维。 为了使用便捷,Pop Animation框架提供了很多现成的POPAnimatableProperty预定义,你只需要使用预定义的propertyWithName来初始化POPAnimatableProperty便可,比如以下一些预定义的propertyWithName:
 
 
 
  1. kPOPLayerBackgroundColor 
  2. ... 
  3. kPOPViewAlpha 
  4. ... 
 
这样预定义的POPAnimatableProperty已经帮你设置好writeBlock和readBlock。 下面的一些基于POPPropertyAnimation的动画都提供了快捷的方法,直接传入propertyWithName便创建好了特定property的动画了。 下面列举的各个实例都可以在这里找到:https://github.com/kejinlu/facebook-pop-sample。
 
1.POPBasicAnimation
 
基本动画,接口方面和CABasicAniamtion很相似,使用可以提供初始值fromValue,这个 终点值toValue,动画时长duration以及决定动画节奏的timingFunction。timingFunction直接使用的CAMediaTimingFunction,是使用一个横向纵向都为一个单位的拥有两个控制点的贝赛尔曲线来描述的,横坐标为时间,纵坐标为动画进度。
 
这里举一个View移动的例子:
 
 
  1. NSInteger height = CGRectGetHeight(self.view.bounds); 
    NSInteger width = CGRectGetWidth(self.view.bounds); 
     
    CGFloat centerX = arc4random() % width; 
    CGFloat centerY = arc4random() % height; 
     
    POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; 
    anim.toValue = [NSValue valueWithCGPoint:CGPointMake(centerX, centerY)]; 
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    anim.duration = 0.4; 
    [self.testView pop_addAnimation:anim forKey:@"centerAnimation"]; 
 
这里self.view上放了一个用于动画的testView,然后取一个随机坐标,进行动画。
 
2.PopSpringAnimation
 
弹簧动画是Bezier曲线无法表述的,所以无法使用PopBasicAniamtion来实现。PopSpringAnimation便是专门用来实现弹簧动画的。
 
 
 
  1. POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; 
     
    NSInteger height = CGRectGetHeight(self.view.bounds); 
    NSInteger width = CGRectGetWidth(self.view.bounds); 
     
    CGFloat centerX = arc4random() % width; 
    CGFloat centerY = arc4random() % height; 
     
    anim.toValue = [NSValue valueWithCGPoint:CGPointMake(centerX, centerY)]; 
    anim.springBounciness = 16; 
    anim.springSpeed = 6; 
    [self.testView pop_addAnimation:anim forKey:@"center"]; 
 
 
 
这个例子的动画和上面的基本动画很相似,都是一个view的移动,但是这里有弹簧效果。POPSpringAnimation主要就是需要注意下几个参数的含义:
 
1.springBounciness 弹簧弹力 取值范围为[0, 20],默认值为4
2.springSpeed 弹簧速度,速度越快,动画时间越短 [0, 20],默认为12,和springBounciness一起决定着弹簧动画的效果
3.dynamicsTension 弹簧的张力
4.dynamicsFriction 弹簧摩擦
5.dynamicsMass 质量 。张力,摩擦,质量这三者可以从更细的粒度上替代springBounciness和springSpeed控制弹簧动画的效果
 
3.PopDecayAnimation
 
基于Bezier曲线的timingFuntion同样无法表述Decay Aniamtion,所以Pop就单独实现了一个 PopDecayAnimation,用于衰减动画。衰减动画一个很常见的地方就是 UIScrollView 滑动松开后的减速,这里就基于UIView实现一个自己的ScrollView,然后使用PopDecayAnimation实现 此代码可以详细参见 KKScrollView 的实现,当滑动手势结束时,根据结束的加速度,给衰减动画一个初始的velocity,用来决定衰减的时长。
 
 
4.POPCustomAnimation
 
POPCustomAnimation 并不是基于POPPropertyAnimation的,它直接继承自PopAnimation用于创建自定义动画用的,通过POPCustomAnimationBlock类型的block进行初始化,
 
 
  1. typedef BOOL (^POPCustomAnimationBlock)(id target, POPCustomAnimation *animation); 
 
此block会在界面的每一帧更新的时候被调用,创建者需要在block中根据当前currentTime和elapsedTime来决定如何更新target的相关属性,以实现特定的动画。当你需要结束动画的时候就在block中返回NO,否则返回YES。

四.Pop Animation相比于Core Animation的优点
 
Pop Animation应用于CALayer时,在动画运行的任何时刻,layer和其presentationLayer的相关属性值始终保持一致,而Core Animation做不到。 
 
Pop Animation可以应用任何NSObject的对象,而Core Aniamtion必须是CALayer。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值