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

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 源码地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容