Facebook POP 使用指南

简介:

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

安装

Pop支持 CocoaPods 安装,将下面一行代码添加到你的项目中的 Podfile 中:

    pod 'pop', '~> 1.0'

注意,bug会在主分支上面进行修复,然后在指定的分支上进行发布。如果你喜欢尝试最新的不大稳定的版本,你可以通过以下入口来访问主分支:
pod 'pop', :git => 'https://github.com/facebook/pop.git'

使用

Pop 支持Core Animation 中的显式动画类型,你可以通过导入头文件来使用它:

   #import <pop/POP.h>

开始动画、停止动画与更新动画

开始执行一个动画,你可以将动画添加到一个对象中:

POPSpringAnimation *anim = [POPSpringAnimation animation];
...
[layer pop_addAnimation:anim forKey:@"myKey"];

停止一个动画,你可以根据一个键值来从对象中移除掉:
[layer pop_removeAnimationForKey:@"myKey"];

你也可以根据键值来查询已经存在的动画,你可以在执行动画效果的同时来修改toValue属性来实时更新动画效果:
anim = [layer pop_animationForKey:@"myKey"];
if (anim) {
  /* update to value to new destination */
  anim.toValue = @(42.0);
} else {
  /* create and start a new animation */
  ....
}

注意,虽然上述示例中用到了一个layer,但是Pop动画引擎是基于 NSObject 所写的一个category,任何继承自NSObject的对象都可以使用Pop动画引擎。

动画类型

Pop支持4种动画类型:弹簧效果、衰减效果、基本动画效果与自定义动画效果。

弹簧效果可以用来实现仿真的物理弹簧特效,在下面的这个例子中,我们用弹簧效果来对一个layer的尺寸进行缩放:

效果图:

源码:

#import "ViewController.h"
#import "POP.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建layer
    CALayer *layer        = [CALayer layer];
    layer.frame           = CGRectMake(0, 0, 50, 50);
    layer.backgroundColor = [UIColor cyanColor].CGColor;
    layer.cornerRadius    = 25.f;
    layer.position        = self.view.center;
    [self.view.layer addSublayer:layer];
    
    // 执行Spring动画
    POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    anim.toValue             = [NSValue valueWithCGPoint:CGPointMake(3.f, 3.f)];
    anim.springSpeed         = 0.f;
    [layer pop_addAnimation:anim forKey:@"ScaleXY"];
}

@end

衰减效果可以用来模拟真实的物理减速效果,在下面的例子中,我们用衰减效果来对一个view的拖拽停止执行减速效果。

效果图:

源码:

#import "ViewController.h"
#import "POP.h"

@interface ViewController ()<POPAnimationDelegate>

@property(nonatomic) UIControl *dragView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 初始化dragView
    self.dragView                    = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    self.dragView.center             = self.view.center;
    self.dragView.layer.cornerRadius = CGRectGetWidth(self.dragView.bounds)/2;
    self.dragView.backgroundColor    = [UIColor cyanColor];
    [self.view addSubview:self.dragView];
    [self.dragView addTarget:self
                      action:@selector(touchDown:)
            forControlEvents:UIControlEventTouchDown];
    
    
    // 添加手势
    UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                                 action:@selector(handlePan:)];
    [self.dragView addGestureRecognizer:recognizer];
}

- (void)touchDown:(UIControl *)sender {
    [sender.layer pop_removeAllAnimations];
}

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    // 拖拽
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    
    // 拖拽动作结束
    if(recognizer.state == UIGestureRecognizerStateEnded)
    {
        // 计算出移动的速度
        CGPoint velocity = [recognizer velocityInView:self.view];
        
        // 衰退减速动画
        POPDecayAnimation *positionAnimation = \
        [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition];
        
        // 设置代理
        positionAnimation.delegate = self;
        
        // 设置速度动画
        positionAnimation.velocity = [NSValue valueWithCGPoint:velocity];
        
        // 添加动画
        [recognizer.view.layer pop_addAnimation:positionAnimation
                                         forKey:@"layerPositionAnimation"];
    }
}

@end

基本动画效果可以指定具体的动画时间,与 CoreAnimation 中的 CABasicAnimation 的用法极为类似,在下面的例子中,我们用基本动画效果来设置一个view的alpha值。

效果图:

源码:

#import "ViewController.h"
#import "POP.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 创建view
    UIView *showView            = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    showView.alpha              = 0.f;
    showView.layer.cornerRadius = 50.f;
    showView.center             = self.view.center;
    showView.backgroundColor    = [UIColor cyanColor];
    [self.view addSubview:showView];

    // 执行基本动画效果
    POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha];
    anim.timingFunction     = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.fromValue          = @(0.0);
    anim.toValue            = @(1.0);
    anim.duration           = 4.f;
    [showView pop_addAnimation:anim forKey:@"fade"];
}

@end

自定义动画效果是根据 CADisplayLink 来计算出中间的差值,然后由你来处理输出的值的动画效果,详情请参考相关头文件来获取更多的细节。

属性

属性是通过 POPAnimatableProperty 来定义的。在下面的这个例子中,我们创建出了一个弹簧动画效果并显式的设置它去响应 -[CALayer bounds]

POPSpringAnimation *anim = [POPSpringAnimation animation];
anim.property            = [POPAnimatableProperty propertyWithName:kPOPLayerBounds];

Pop动画引擎本身提供了很多可以做动画的属性供你定制。你可以在这个类里面创建出一个实例对象:
prop = [POPAnimatableProperty propertyWithName:@"com.foo.radio.volume" initializer:^(POPMutableAnimatableProperty *prop) {
  // read value
  prop.readBlock = ^(id obj, CGFloat values[]) {
    values[0] = [obj volume];
  };
  // write value
  prop.writeBlock = ^(id obj, const CGFloat values[]) {
    [obj setVolume:values[0]];
  };
  // dynamics threshold
  prop.threshold = 0.01;
}];

anim.property = prop;

为了了解更多的可以做动画效果的属性,你可以参考  POPAnimatableProperty.h  查看更多的细节。

目录
相关文章
|
6月前
|
缓存 网络协议 Linux
百度搜索:蓝易云【解决github push/pull报错443】
通过以上方法,你有望解决GitHub push/pull报错443的问题。如果问题仍然存在,建议检查GitHub的状态页面,看是否有正在维护或故障的情况。
136 3
|
6月前
|
数据采集 存储 Scala
挖掘网络宝藏:利用Scala和Fetch库下载Facebook网页内容
本文介绍了如何使用Scala和Fetch库下载Facebook网页内容,同时通过爬虫代理服务(以亿牛云为例)绕过网络限制。代码示例展示了配置代理服务器、多线程爬取及内容存储的过程。注意实际应用时需替换代理服务器配置和目标URL,并考虑应对复杂的反爬虫机制。此方法兼顾匿名性和效率。
挖掘网络宝藏:利用Scala和Fetch库下载Facebook网页内容
|
机器学习/深度学习 SQL 存储
|
搜索推荐
带你读《Elastic Stack 实战手册》之70:——4.1.2.实现主流搜索引擎广告置顶显示效果(上)
带你读《Elastic Stack 实战手册》之70:——4.1.2.实现主流搜索引擎广告置顶显示效果(上)
104 0
带你读《Elastic Stack 实战手册》之70:——4.1.2.实现主流搜索引擎广告置顶显示效果(上)
|
自然语言处理 搜索推荐 NoSQL
带你读《Elastic Stack 实战手册》之70:——4.1.2.实现主流搜索引擎广告置顶显示效果(下)
带你读《Elastic Stack 实战手册》之70:——4.1.2.实现主流搜索引擎广告置顶显示效果(下)
105 0
|
开发工具 开发者
友盟推送集成方案攻略(Push SDK 6.2.0版本)
友盟推送集成方案攻略(Push SDK 6.2.0版本)
友盟推送集成方案攻略(Push SDK 6.2.0版本)
|
自然语言处理 搜索推荐 NoSQL
实现主流搜索引擎广告置顶显示效果— Elastic Stack 实战手册
本应用实践,主要针对 Elasticsearch 如何实现类似百度广告置顶显示,给定商品数据的效果展开介绍,例如实现置顶显示某特定数据,像搜索某关键词,出现关联广告置顶显示的效果。
796 0
实现主流搜索引擎广告置顶显示效果— Elastic Stack 实战手册
|
移动开发 Java 程序员
Facebook 将神奇动画引擎 Pop 开源了!
Facebook 2月发布的新闻类应用Paper,因为其灵动的用户界面和交互,成为近来最令人眼前一亮的移动产品之一。 而这个产品的背后是2011年Facebook收购的Push Pop Press,创始人是分别在Apple任设计师和工程师的Mike Matas与Kimon Tsinteris。他们的合作者还有传奇人物Bret Victor。他们为美国前副总统Al Gore开发的电子书Our Choice当时就曾技惊四座。
349 0
Facebook 将神奇动画引擎 Pop 开源了!
|
存储 Kubernetes JavaScript
GitHub上广受欢迎的下载神器:youtube-dl
GitHub上广受欢迎的下载神器:youtube-dl
417 0
GitHub上广受欢迎的下载神器:youtube-dl
|
机器学习/深度学习 人工智能 大数据
全球最火DL课程Fast.ai 2020版今日上线!我们拿到了独家授权,中文版同步免费放出
全球最火DL课程Fast.ai 2020版今日上线!我们拿到了独家授权,中文版同步免费放出
406 0