iOS POP动画简单使用

作者: SunshineBrother | 来源:发表于2017-07-11 14:35 被阅读1074次

    POP背后的开发者是 Kimon Tsinteris, Push Pop Press 的联合创始人,曾经在Apple担任高级工程师,并参与了 iPhone 和 iPad 上软件的研发(iPhone的指南针以及地图)。2011年的时候 Facebook 收购了他的公司,此后他便加入了 Facebook 负责 Facebook iOS 版本的开发。

    POP 使用 Objective-C++ 编写,Objective-C++ 是对 C++ 的扩展,就像 Objective-C 是 C 的扩展。而至于为什么他们用 Objective-C++ 而不是纯粹的 Objective-C,原因是他们更喜欢 Objective-C++ 的语法特性所提供的便利

    POP动画是一个十分受欢迎的动画,在这个框架刚出来一周的时候点赞👍量都超过3k,现在点赞量达到17.8k。身为一个iOS开发者必须对这个框架有一定的了解。

    7B0CCB7A-9F02-4948-9F19-709EDEC73218.png

    效果图

    POP动画应用.gif

    我在项目中目录

    • pop基础介绍
    • pop项目中PropertyNamed简单介绍
    • 弹性动画
    • 弹出小卡片
    • 画圆
    • 进度条
    • 图像折叠

    想要看代码的可以点击这里

    项目参考了pop-handapppopping这两个项目,内容也是基于这两个项目写的。

    【注意】

    在使用pop-handapp的时候,我们pod以后会报Cannot initialize a member subobject of type 'NSUInteger' (aka 'unsigned long') with an rvalue of type 'nullptr_t'这个错误,解决办法,我先把POP库移除,然后随便添加一个AFNetworking库,然后在添加POP库,为啥这样做,我也不知道哦,反正我是这样解决问题的。

    参考文献

    Facebook POP动效库使用教程
    Facebook Pop 使用指南
    Facebook POP 进阶指南

    基本类型

    POP基础.png

    使用之前需要先倒入#import <POP.h>

    POPBasicAnimation
    基础使用
     /*
         设置动画至少需要三步
         1、定义一个animation对象 并指定对应的动画属性
         2、设置初始值和默认值(初始值可以不指定 会默认从当前值开始)
         3、添加到想产生动画的对象上
         
         POPBasicAnimation可配置的属性与默认值为
         duration:0.4    //动画间隔
    
         */
        POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionX];
        animation.toValue = @(_BaseView.center.y + 200);
        animation.beginTime = CACurrentMediaTime() + 1.0f;
        [_BaseView pop_addAnimation:animation forKey:@"BasicAnimation"];
    
    

    我们点击进入POPBasicAnimation里面

    • 两个初始化方法

    • + (instancetype)animation;

    • + (instancetype)animationWithPropertyNamed

    • 四个动画方式

    • kCAMediaTimingFunctionLinear

    • kCAMediaTimingFunctionEaseIn

    • kCAMediaTimingFunctionEaseOut

    • kCAMediaTimingFunctionEaseInEaseOut

    • 两个属性

    • duration

    • timingFunction

    POPSpringAnimation

    POPSpringAnimation也许是大多数人使用POP的理由 其提供一个类似弹簧一般的动画效果

    POPSpringAnimation可配置的属性与默认值为

    • springBounciness //[0-20] 弹力 越大则震动幅度越大

    • springSpeed //[0-20] 速度 越大则动画结束越快

    • dynamicsTension //拉力 接下来这三个都跟物理力学模拟相关 数值调整起来也很费时 没事不建议使用哈

    • dynamicsFriction //摩擦 同上

    • dynamicsMass //质量 同上

    【注意】
    POPSpringAnimation是没有duration字段的 其动画持续时间由以上几个参数决定

    简单实用
     POPSpringAnimation *aniSpring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
        aniSpring.toValue = @(_BaseView.center.x + 100);
        aniSpring.beginTime = CACurrentMediaTime();
        aniSpring.springBounciness = 10.0;
        [_BaseView pop_addAnimation:aniSpring forKey:@"POPSpringAnimation"];
    

    POPDecayAnimation

    Decay Animation 就是 POP 提供的另外一个非常特别的动画,他实现了一个衰减的效果。这个动画有一个重要的参数 velocity(速率),一般并不用于物体的自发动画,而是与用户的交互共生

    Decay 的动画没有 toValue 只有 fromValue,然后按照 velocity 来做衰减操作

    想要理解更深POPDecayAnimation,可以参考小球碰壁反弹效果

    代码
    #import "DecayAnimationTwo.h"
    #import <POP.h>
    @interface DecayAnimationTwo ()<POPAnimationDelegate>
    @property (nonatomic,strong) UIView *baseView;
    @end
    
    @implementation DecayAnimationTwo
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        self.title = @"碰壁反弹效果";
        
        
        _baseView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
        _baseView.center = self.view.center;
        _baseView.layer.masksToBounds = YES;
        _baseView.layer.cornerRadius = _baseView.bounds.size.width/2;
        _baseView.backgroundColor = [UIColor redColor];
        [self.view addSubview:_baseView];
        
        
        //拖拽手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(PanGesture:)];
        [_baseView addGestureRecognizer:pan];
     
    }
    
    
    //拖拽手势
    - (void)PanGesture:(UIPanGestureRecognizer*)pan{
        //在拖动过程中
        //取出偏移量
        CGPoint offset = [pan translationInView:self.view];
        //让baseView平移
        _baseView.transform = CGAffineTransformTranslate(_baseView.transform, offset.x, offset.y);
        //平移完之后将偏移量重新置为0
        //这很重要,要记住
        [pan setTranslation:CGPointZero inView:self.view];
        
        
        //当拖动手势结束的时候,开始动画
        if (pan.state == UIGestureRecognizerStateEnded) {
            
            POPDecayAnimation *decayAnimation = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition];
            CGPoint velocity = [pan velocityInView:self.view];
            decayAnimation.velocity = [NSValue valueWithCGPoint:velocity];
            [_baseView.layer pop_addAnimation:decayAnimation forKey:@"layerPositionAnimation"];
            
            decayAnimation.delegate = self;
            
        }
     
    }
    
    #pragma mark - POPAnimationDelegate
    ///在小球弹动的过程中判断是否碰壁
    - (void)pop_animationDidApply:(POPDecayAnimation *)anim
    {
        BOOL baseViewInsideOfSuperView = CGRectContainsRect(self.view.frame, self.baseView.frame);
        if (!baseViewInsideOfSuperView) {
           
            CGPoint currentVelocity = [anim.velocity CGPointValue];
            CGPoint velocity = CGPointMake(currentVelocity.x, -currentVelocity.y);
            POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPosition];
            positionAnimation.velocity = [NSValue valueWithCGPoint:velocity];
            positionAnimation.toValue = [NSValue valueWithCGPoint:self.view.center];
            [self.baseView.layer pop_addAnimation:positionAnimation forKey:@"layerPositionAnimation"];
        }
        
    }
    
    @end
    

    POPAnimatableProperty

    效果图


    POPAnimatableProperty.gif
    代码
     
        /*
         其组成就是一个readBlock一个writeBlock和一个threashold
         
         readBlock告诉POP当前的属性值
         writeBlock中修改变化后的属性值
         threashold决定了动画变化间隔的阈值 值越大writeBlock的调用次数越少
         */
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100)];
        label.textAlignment = NSTextAlignmentCenter;
        [self.view addSubview:label];
        
        POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"countdown" initializer:^(POPMutableAnimatableProperty *prop) {
           
            prop.readBlock = ^(id obj, CGFloat values[]) {
               
            };
            
            prop.writeBlock = ^(id obj, const CGFloat values[]) {
                UILabel *label = (UILabel*)obj;
                label.text = [NSString stringWithFormat:@"%02d:%02d:%02d",(int)values[0]/60,(int)values[0]%60,(int)(values[0]*100)%100];
            };
           
            prop.threshold = 0.01;
        }];
        
        
        
        POPBasicAnimation *anBasic = [POPBasicAnimation linearAnimation];   //秒表当然必须是线性的时间函数
        anBasic.property = prop;    //自定义属性
        anBasic.fromValue = @(0);   //从0开始
        anBasic.toValue = @(3*60);  //180秒
        anBasic.duration = 3*60;    //持续3分钟
        anBasic.beginTime = CACurrentMediaTime();
        [label pop_addAnimation:anBasic forKey:@"countdown"];
    
    

    PropertyNamed

    一些人可能对PropertyNamed的一些属性不太了解,我这里做了一个简单的demo,对一些简单的属性做了一些解释。

    效果图
    PropertyNamed.gif

    譬如kPOPViewCenter

     POPBasicAnimation *basicAnimation = [POPBasicAnimation animation];
        basicAnimation.property = [POPAnimatableProperty propertyWithName:kPOPViewCenter];
        basicAnimation.toValue=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
        [_baseView pop_addAnimation:basicAnimation forKey:@"kPOPViewCenter"];
    
    

    具体代码请参考这里,也可以参考详解Fecebook PoP API 及 属性使用!这篇文章,来对属性进行补充

    相关文章

      网友评论

      • ZhengYaWei:文章开头第一段的这个背景效果语法是什么
        SunshineBrother:http://www.jianshu.com/p/q81RER markdown语法

      本文标题:iOS POP动画简单使用

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