
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動(dòng)畫在github上的官方解釋,大體上的意思是pop是一個(gè)extensible(可擴(kuò)展)的動(dòng)畫引擎,提供基礎(chǔ)的Basic 靜態(tài)動(dòng)畫以及支持彈簧和衰減動(dòng)畫,用來(lái)構(gòu)建高可用性的真實(shí)、物理特性的交互體驗(yàn),使用oc作為基礎(chǔ),可用戶擴(kuò)展到任何的oc的Object的屬性,是一個(gè)非常易于測(cè)試的框架,并且在Facebook自家的Paper上應(yīng)用。
pop首先是一個(gè)動(dòng)畫引擎,那本質(zhì)上不再是基于apple的CoreAnimation框架的,是自己實(shí)現(xiàn)的一套跟CoreAnimation一樣的動(dòng)畫引擎框架,內(nèi)部使用了CADisplayer的每秒60幀高素質(zhì)的渲染技術(shù),充分使用了GPU的能力,性能表現(xiàn)很樂觀,而能用作任何基于NSObject上,又增加了擴(kuò)展性,比如說(shuō)UIView背景顏色的動(dòng)態(tài)切換,比如說(shuō)聲音的漸隱漸顯等等,這是對(duì)CA不足的充分補(bǔ)充,而引出的physics特性,更引發(fā)了apple后來(lái)推出了UIDynamic(UIKit動(dòng)力學(xué))來(lái)彌補(bǔ)iOS平臺(tái)上的物理特性動(dòng)畫的不足,也大大簡(jiǎn)化了動(dòng)畫的開發(fā)難度。POP 使用 Objective-C++ 編寫,Objective-C++ 是對(duì) C++ 的擴(kuò)展,就像 Objective-C 是 C 的擴(kuò)展。而至于為什么他們用 Objective-C++ 而不是純粹的 Objective-C,原因是他們更喜歡 Objective-C++ 的語(yǔ)法特性所提供的便利。那我們弄清楚了pop的本質(zhì),就開始介紹一下這個(gè)框架。
基本的pop動(dòng)畫的使用我就不再贅述,很多文章都有介紹,我在剛接觸的pop的時(shí)候有很多疑問,主要是在實(shí)際運(yùn)用的時(shí)候出現(xiàn)的代碼實(shí)踐的問題,因?yàn)橹耙恢笔怯肅A的,總會(huì)用CA的用法來(lái)尋找pop的使用技巧,那么就有以下幾個(gè)問題要搞清楚:
1.具有多個(gè)動(dòng)畫的聯(lián)合動(dòng)畫如何實(shí)現(xiàn),CA中有CAAnimationGroup的概念,能實(shí)現(xiàn)動(dòng)畫組,pop中該怎么辦?
2.有沒有重復(fù)播放動(dòng)畫的概念,因?yàn)橛行﹦?dòng)畫是必須重復(fù)播放的。
3.在現(xiàn)在大量使用autolayout的布局的時(shí)候,如何使用pop動(dòng)畫
結(jié)合以上的問題,我自己做了一個(gè)卡片切換動(dòng)畫的Demo來(lái)說(shuō)明一下。

卡片設(shè)計(jì)比較粗糙,沒有設(shè)置卡片上明確的細(xì)小的分欄和文字切換,只是簡(jiǎn)單的模仿了卡片切換和卡片上圓環(huán)的切換。
動(dòng)畫組的概念,這個(gè)問題在做的時(shí)候不糾結(jié)了,因?yàn)閜op提供pop_addAnimation這樣的API,實(shí)際上要想實(shí)現(xiàn)動(dòng)畫組概念,在實(shí)踐中就將生產(chǎn)Animation的代碼單獨(dú)封裝成函數(shù),然后多次調(diào)用pop_addAnimation就好了。比方說(shuō),我就會(huì)這么干
-(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"];
}
將上述對(duì)cardView增加動(dòng)畫的方法寫好,然后多次調(diào)用
[self setScaleWithScalePercent:scalePercent Duration:0.0001f Card:card];
[self setRorationWithAngle:rotation Duration:0.001f Card:card];
對(duì)于重復(fù)的動(dòng)畫使用,可以利用如下:
-(void)performAnimation
{
[self setAnimationWithBounciness:self.bouncinessSlider.value andSpeed:self.speedSlider.value];
}
定義好執(zhí)行方法,在completionBlock中重復(fù)調(diào)用執(zhí)行動(dòng)畫的方法就Ok,當(dāng)然,你也可以對(duì)pop動(dòng)畫對(duì)象再封裝,實(shí)現(xiàn)重復(fù)次數(shù)。
anim.completionBlock = ^(POPAnimation *anim, BOOL finished)
{
if (finished) {
[self performAnimation];
}
};
對(duì)于autolayout的動(dòng)畫
有人寫過(guò)這樣的例子,以下是代碼,pop是支持更新layout的約束的,這對(duì)更新具體某個(gè)約束是比較有效的,而如果你在做某個(gè)類似翻轉(zhuǎn)動(dòng)畫的時(shí)候,必定要用到layer層動(dòng)畫,那單單靠更新約束就不太能滿足要求,但是恰好你在使用Pop的layer層動(dòng)畫的時(shí)候,該layer屬于的View上有用約束建立的控件,就比較難以處理,我個(gè)人的意見是,做layer層的動(dòng)畫,那上面的其他控件干脆也用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"];
以上就是一切使用問題的總結(jié),詳細(xì)的使用可以參考源碼。