美文网首页iOS 知识点iOS动画效果iOS -- Demo
iOS动効-利用POP动画实现卡片切换动画

iOS动効-利用POP动画实现卡片切换动画

作者: Neo_joke | 来源:发表于2015-07-02 00:18 被阅读16585次

    Pop is an extensible animation engine for iOS and OS X. In addition to basic static animations, it supports spring and decay dynamic animations, making it useful for building realistic, physics-based interactions. The API allows quick integration with existing Objective-C codebases and enables the animation of any property on any object. It's a mature and well-tested framework that drives all the animations and transitions in Paper.

    以上是pop动画在github上的官方解释,大体上的意思是pop是一个extensible(可扩展)的动画引擎,提供基础的Basic 静态动画以及支持弹簧和衰减动画,用来构建高可用性的真实、物理特性的交互体验,使用oc作为基础,可用户扩展到任何的oc的Object的属性,是一个非常易于测试的框架,并且在Facebook自家的Paper上应用。

    pop首先是一个动画引擎,那本质上不再是基于apple的CoreAnimation框架的,是自己实现的一套跟CoreAnimation一样的动画引擎框架,内部使用了CADisplayer的每秒60帧高素质的渲染技术,充分使用了GPU的能力,性能表现很乐观,而能用作任何基于NSObject上,又增加了扩展性,比如说UIView背景颜色的动态切换,比如说声音的渐隐渐显等等,这是对CA不足的充分补充,而引出的physics特性,更引发了apple后来推出了UIDynamic(UIKit动力学)来弥补iOS平台上的物理特性动画的不足,也大大简化了动画的开发难度。POP 使用 Objective-C++ 编写,Objective-C++ 是对 C++ 的扩展,就像 Objective-C 是 C 的扩展。而至于为什么他们用 Objective-C++ 而不是纯粹的 Objective-C,原因是他们更喜欢 Objective-C++ 的语法特性所提供的便利。那我们弄清楚了pop的本质,就开始介绍一下这个框架。

    基本的pop动画的使用我就不再赘述,很多文章都有介绍,我在刚接触的pop的时候有很多疑问,主要是在实际运用的时候出现的代码实践的问题,因为之前一直是用CA的,总会用CA的用法来寻找pop的使用技巧,那么就有以下几个问题要搞清楚:

    1.具有多个动画的联合动画如何实现,CA中有CAAnimationGroup的概念,能实现动画组,pop中该怎么办?

    2.有没有重复播放动画的概念,因为有些动画是必须重复播放的。

    3.在现在大量使用autolayout的布局的时候,如何使用pop动画

    结合以上的问题,我自己做了一个卡片切换动画的Demo来说明一下。

    卡片切换的交互动画

    卡片设计比较粗糙,没有设置卡片上明确的细小的分栏和文字切换,只是简单的模仿了卡片切换和卡片上圆环的切换。

    动画组的概念,这个问题在做的时候不纠结了,因为pop提供pop_addAnimation这样的API,实际上要想实现动画组概念,在实践中就将生产Animation的代码单独封装成函数,然后多次调用pop_addAnimation就好了。比方说,我就会这么干

    -(void)setCenter:(CGPoint)center Duration:(CGFloat)duration Card:(cardView *)card Index:(NSUInteger)index{

    POPBasicAnimation * bAni = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];

    bAni.toValue = [NSValue valueWithCGPoint:center];

    bAni.duration = duration;

    [bAni setCompletionBlock:^(POPAnimation *ani, BOOL is) {

    if (is) {

    card.hidden = NO;

    }

    }];

    [card pop_addAnimation:bAni forKey:@"center"];

    }

    -(void)setScaleWithScalePercent:(CGFloat) percent Duration:(CGFloat)duration Card:(cardView *)card{

    POPBasicAnimation * bAni = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];

    bAni.toValue = [NSValue valueWithCGSize:CGSizeMake(percent, percent)];

    bAni.duration = duration;

    [card.layer pop_addAnimation:bAni forKey:@"123"];

    }

    -(void)setRorationWithAngle:(CGFloat)angele Duration:(CGFloat)duration Card:(cardView *)card{

    POPBasicAnimation * bAni = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];

    bAni.duration = duration;

    bAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    bAni.toValue = [NSNumber numberWithFloat:angele];

    [card.layer pop_addAnimation:bAni forKey:@"213"];

    }

    将上述对cardView增加动画的方法写好,然后多次调用

    [self setScaleWithScalePercent:scalePercent Duration:0.0001f Card:card];

    [self setRorationWithAngle:rotation Duration:0.001f Card:card];

    对于重复的动画使用,可以利用如下:

    -(void)performAnimation

    {

    [self setAnimationWithBounciness:self.bouncinessSlider.value andSpeed:self.speedSlider.value];

    }

    定义好执行方法,在completionBlock中重复调用执行动画的方法就Ok,当然,你也可以对pop动画对象再封装,实现重复次数。

    anim.completionBlock = ^(POPAnimation *anim, BOOL finished)

    {

    if (finished) {

    [self performAnimation];

    }

    };

    对于autolayout的动画

    有人写过这样的例子,以下是代码,pop是支持更新layout的约束的,这对更新具体某个约束是比较有效的,而如果你在做某个类似翻转动画的时候,必定要用到layer层动画,那单单靠更新约束就不太能满足要求,但是恰好你在使用Pop的layer层动画的时候,该layer属于的View上有用约束建立的控件,就比较难以处理,我个人的意见是,做layer层的动画,那上面的其他控件干脆也用frame布局。

    POPAnimatableProperty *constantProperty = [POPAnimatableProperty propertyWithName:@"constant" initializer:^(POPMutableAnimatableProperty *prop){

    prop.readBlock = ^(NSLayoutConstraint *layoutConstraint, CGFloat values[]) {

    values[0] = [layoutConstraint constant];

    };

    prop.writeBlock = ^(NSLayoutConstraint *layoutConstraint, const CGFloat values[]) {

    [layoutConstraint setConstant:values[0]];

    };

    }];

    POPSpringAnimation *constantAnimation = [POPSpringAnimation animation];

    constantAnimation.property = constantProperty;

    constantAnimation.fromValue = @(_layoutConstraint.constant);

    constantAnimation.toValue = @(200);

    [_layoutConstraint pop_addAnimation:constantAnimation forKey:@"constantAnimation"];

    以上就是一切使用问题的总结,详细的使用可以参考源码。

    github 源码地址

    相关文章

      网友评论

      • 卓敦:这个有向下滑的时候,上一张回来的效果吗
      • 霸把:大佬 请问怎么获取到当前显示的是数据源数组中的第几个呢???
        我自己照你的学习了一下。想在在下面显示出来选中第几个以及想把cardview里面的点击事件通过block传出来 发现获取不到当前显示的是第几个。。。
      • 进击的小巨牛:现在这个Demo里每个CardView显示的内容都是一样的,如果数组里的每个元素都不一样怎么循环显示呢?就是类似轮播图那种呢?
      • 话少为环保:请教楼主
        这个 ‘kPOPLayoutConstraintConstant’ 动画属性应该怎么用呢 我现在用Masonry布局,能不能用pop的‘kPOPLayoutConstraintConstant’属性更改约束实现动画效果呢?:cry:
      • 3f58e786b546:Mark一下
      • 卧龙小:已经 star ,很不错
      • 郑州程序员王一:楼主,你好,我想问下,您认为iOS自己家的动画库和POP的区别是什么,您认为哪个优势更好呢,我是菜鸟,恳请楼主解开我的迷惑
        Neo_joke:@齐广东 @郑州程序员王一 Pop是用objective-C++写的,但不是调用C++接口,没有这个概念,只不过是用objective-C++的语法特性,底层使用CADisplayLink和实现了CAMediaTiming协议,使其脱离了CALayer成为与CoreAnimation同等级别的动画库。
        郑州程序员王一:@齐广东 谢谢
        1ace156a39cd:@郑州程序员王一 POP动画底层实现是C++接口,而系统提供动画CoreAnimation是OC,POP优势,可实现复杂动画效果,只需要细心下来慢慢研究一下就可以,CoreAnimation,直接面对开发者,能满足基本动画实现,简单易用。(以上评论仅代表个人观点,如喜欢本人,或者技术交流可以加QQ群139852091。mark--本群为技术群,老司机开车止步,开车请加417464943)
      • SuDream: 大神.我能加你QQ吗?我们公司要做这个效果,跪求大神指点,求大神救命
      • 7d4cce1d3b8c:你好,最近也在研究pop,请问pop有什么方式来实现视图沿某一曲线位移的效果吗?往不吝赐教,谢谢。
        我的大名叫小爱:应该是自定义的吧 CA里面比较容易实现
        9086311b25b8:@7d4cce1d3b8c 这个解决了吗?我也想实现这个效果
      • 799aa89dc219:大神 能不能写点注释 有的地方看不太懂 :smile:
      • borjigeen_narsu:很不错,学习了!
      • KevinMK:不错不错,赞赞赞

      本文标题:iOS动効-利用POP动画实现卡片切换动画

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