你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> POP介紹與使用實踐(快速上手動畫)

POP介紹與使用實踐(快速上手動畫)

編輯:IOS開發基礎

dancing-dave-minion-510835_640.jpg

作者:裡脊串 授權本站轉載。

前言

動畫在APP開發過程中,大家多多少少都會接觸到,而且隨著iOS7的扁平化風格啟用之後,越來越多的APP開始嘗試加入各種絢麗的動畫交互效果以增加APP的用戶體驗。(當然,還是以國外的APP居多)

有過相關開發經驗的同學肯定知道在iOS中,動畫相關的部分都是基於Core Animation,但是今天我們不討論Core Animation。今天的主角是POP -來自於Facebook的動畫引擎(其實我不喜歡把POP定義為動畫引擎 我願意稱它為函數發生器)

介紹

官方地址 https://github.com/facebook/pop

官方介紹(翻譯版)

POP是一個在iOS與OS X上通用的極具擴展性的動畫引擎。它在基本的靜態動畫的基礎上增加的彈簧動畫與衰減動畫,使之能創造出更真實更具物理性的交互動畫。POP的API可以快速的與現有的ObjC代碼集成並可以作用於任意對象的任意屬性。

POP是個相當成熟且久經考驗的框架,Facebook出品的令人驚歎的Paper應用中的所有動畫和效果即出自POP。

安裝方式還是推薦使用CocoaPod。

pod 'pop', '~> 1.0'

POP的神奇之處在於,它是獨立與Core Animation的存在。所以,忘記Core Animation吧,忘記Layer Tree吧,迎接一個簡單的明天!(LOL 開玩笑的~:) 很多地方還是會需要Core Animation的,不過說不定哪天蘋果大發善心,將動畫相關的部分向POP借鑒一點也不是不可能的(比如SpriteKit就借鑒了Cocos2D :)

使用

POP默認支持三種動畫,但同時也支持自定義動畫。

  • POPBasicAnimation

  • POPSpringAnimation

  • POPDecayAnimation

  • POPCustomAnimation //自定義動畫

這裡我們只討論前三種(因為自定義動畫我也沒用過 :) 先來看看官方的示例代碼吧。

官方代碼示例

//Basic animations can be used to interpolate values over a specified time period. To use an ease-in ease-out animation to animate a view's alpha from 0.0 to 1.0 over the default duration:
POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha];
anim.fromValue = @(0.0);
anim.toValue = @(1.0);
[view pop_addAnimation:anim forKey:@"fade"];
//Spring animations can be used to give objects a delightful bounce. In this example, we use a spring animation to animate a layer's bounds from its current value to (0, 0, 400, 400):
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds];
anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 400, 400)];
[layer pop_addAnimation:anim forKey:@"size"];
//Decay animations can be used to gradually slow an object to a halt. In this example, we decay a layer's positionX from it's current value and velocity 1000pts per second:
POPDecayAnimation *anim = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPositionX];
anim.velocity = @(1000.);
[layer pop_addAnimation:anim forKey:@"slide"];

POPBasicAnimation

POPBasicAnimation使用最廣泛 提供固定時間間隔的動畫(如淡入淡出效果)

代碼示例1

POPBasicAnimation *anBasic = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionX];
anBasic.toValue = @(self.square.center.y+300);
anBasic.beginTime = CACurrentMediaTime() + 1.0f;
[self.square pop_addAnimation:anBasic forKey:@"position"];

其動畫效果如下

1.gif

可以看到,添加一個動畫最少僅需三步

  1. 定義一個animation對象,並指定對應的動畫屬性

  2. 設置初始值和默認值(初始值可以不指定,會默認從當前值開始)

  3. 添加到想產生動畫的對象上

POPBasicAnimation可配置的屬性與默認值為

duration:0.4    //動畫間隔

POPBasicAnimation提供四種timingfunction(很熟悉,對不對? 就是Core Animation中那些)

  • kCAMediaTimingFunctionLinear

  • kCAMediaTimingFunctionEaseIn

  • kCAMediaTimingFunctionEaseOut

  • kCAMediaTimingFunctionEaseInEaseOut

其時間函數分別如下

blob.png

blob.png

blob.png

blob.png

POPSpringAnimation

POPSpringAnimation也許是大多數人使用POP的理由,其提供一個類似彈簧一般的動畫效果(使用後,APP立馬就活潑起來了,有木有?!)

代碼示例23

POPSpringAnimation *anSpring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionX];
anSpring.toValue = @(self.square.center.y+300);
anSpring.beginTime = CACurrentMediaTime() + 1.0f;
anSpring.springBounciness = 10.0f;
[self.square pop_addAnimation:anSpring forKey:@"position"];

其動畫效果如下

2015-03-11-intro-pop-22.gif

POPSpringAnimation可配置的屬性與默認值為

springBounciness:4.0    //[0-20] 彈力 越大則震動幅度越大
springSpeed     :12.0   //[0-20] 速度 越大則動畫結束越快
dynamicsTension :0      //拉力  接下來這三個都跟物理力學模擬相關 數值調整起來也很費時 沒事不建議使用哈
dynamicsFriction:0      //摩擦 同上
dynamicsMass    :0      //質量 同上

注意:POPSpringAnimation是沒有duration字段的,其動畫持續時間由以上幾個參數決定

其時間函數如下

blob.png

POPDecayAnimation

POPDecayAnimation提供一個過阻尼效果(其實Spring是一種欠阻尼效果),可以實現類似UIScrollView的滑動衰減效果(是的 你可以靠它來自己實現一個UIScrollView)

代碼示例3

POPDecayAnimation *anDecay = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPositionX];
anDecay.velocity = @(600);
anDecay.beginTime = CACurrentMediaTime() + 1.0f;
[self.square pop_addAnimation:anDecay forKey:@"position"];

其動畫效果如下

2015-03-11-intro-pop-33.gif

注意:這裡對POPDecayAnimation設置toValue是沒有意義的,會被忽略(因為目的狀態是動態計算得到的)

POPDecayAnimation可配置的屬性與默認值為

deceleration:0.998  //衰減系數(越小則衰減得越快)

注意:POPDecayAnimation也是沒有duration字段的,其動畫持續時間由velocity與deceleration決定

其時間函數如下

blob.png

接下來我們看一下POP默認支持哪些屬性的動畫。打開POPAnimatablePropery.h可以看到如下定義(這些是到目前為止 所支持的屬性 隨著版本的更新 還在不斷的新增中 :)

/**
 Common CALayer property names.
 */
extern NSString * const kPOPLayerBackgroundColor;
extern NSString * const kPOPLayerBounds;
extern NSString * const kPOPLayerCornerRadius;
extern NSString * const kPOPLayerBorderWidth;
extern NSString * const kPOPLayerBorderColor;
extern NSString * const kPOPLayerOpacity;
extern NSString * const kPOPLayerPosition;
extern NSString * const kPOPLayerPositionX;
extern NSString * const kPOPLayerPositionY;
extern NSString * const kPOPLayerRotation;
extern NSString * const kPOPLayerRotationX;
extern NSString * const kPOPLayerRotationY;
extern NSString * const kPOPLayerScaleX;
extern NSString * const kPOPLayerScaleXY;
extern NSString * const kPOPLayerScaleY;
extern NSString * const kPOPLayerSize;
extern NSString * const kPOPLayerSubscaleXY;
extern NSString * const kPOPLayerSubtranslationX;
extern NSString * const kPOPLayerSubtranslationXY;
extern NSString * const kPOPLayerSubtranslationY;
extern NSString * const kPOPLayerSubtranslationZ;
extern NSString * const kPOPLayerTranslationX;
extern NSString * const kPOPLayerTranslationXY;
extern NSString * const kPOPLayerTranslationY;
extern NSString * const kPOPLayerTranslationZ;
extern NSString * const kPOPLayerZPosition;
extern NSString * const kPOPLayerShadowColor;
extern NSString * const kPOPLayerShadowOffset;
extern NSString * const kPOPLayerShadowOpacity;
extern NSString * const kPOPLayerShadowRadius;
/**
 Common CAShapeLayer property names.
 */
extern NSString * const kPOPShapeLayerStrokeStart;
extern NSString * const kPOPShapeLayerStrokeEnd;
extern NSString * const kPOPShapeLayerStrokeColor;
extern NSString * const kPOPShapeLayerFillColor;
/**
 Common NSLayoutConstraint property names.
 */
extern NSString * const kPOPLayoutConstraintConstant;
#if TARGET_OS_IPHONE
/**
 Common UIView property names.
 */
extern NSString * const kPOPViewAlpha;
extern NSString * const kPOPViewBackgroundColor;
extern NSString * const kPOPViewBounds;
extern NSString * const kPOPViewCenter;
extern NSString * const kPOPViewFrame;
extern NSString * const kPOPViewScaleX;
extern NSString * const kPOPViewScaleXY;
extern NSString * const kPOPViewScaleY;
extern NSString * const kPOPViewSize;
extern NSString * const kPOPViewTintColor;
/**
 Common UIScrollView property names.
 */
extern NSString * const kPOPScrollViewContentOffset;
extern NSString * const kPOPScrollViewContentSize;
extern NSString * const kPOPScrollViewZoomScale;
extern NSString * const kPOPScrollViewContentInset;
/**
 Common UITableView property names.
 */
extern NSString * const kPOPTableViewContentOffset;
extern NSString * const kPOPTableViewContentSize;
/**
 Common UICollectionView property names.
 */
extern NSString * const kPOPCollectionViewContentOffset;
extern NSString * const kPOPCollectionViewContentSize;
/**
 Common UINavigationBar property names.
 */
extern NSString * const kPOPNavigationBarBarTintColor;
/**
 Common UIToolbar property names.
 */
extern NSString * const kPOPToolbarBarTintColor;
/**
 Common UITabBar property names.
 */
extern NSString * const kPOPTabBarBarTintColor;
/**
 Common UILabel property names.
 */
extern NSString * const kPOPLabelTextColor;

作為剛接觸POP的一些同學來說,如果在上面看到你希望的某些屬性的話,你可以像官方代碼示例一樣指定這個屬性即可開始動畫了

但是如果你想要的某些屬性不在之上呢,這時候自定義屬性POPAnimatableProperty就排上用場了

自定義屬性

POP默認支持的三種動畫都繼承自POPPropertyAnimation。POPPropertyAnimation中定義了一個叫property的屬性( 之前沒有用到它是因為POP根據不同的默認動畫屬性幫你生成了默認的property) 而這個property則是用來驅動POP的動畫效果中的重要一環。

代碼示例4

POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"prop" initializer:^(POPMutableAnimatableProperty *prop) {
    // read value
    prop.readBlock = ^(id obj, CGFloat values[]) {
    };
    // write value
    prop.writeBlock = ^(id obj, const CGFloat values[]) {
    };
    // dynamics threshold
    prop.threshold = 0.01;
}];

其組成就是一個readBlock一個writeBlock和一個threashold

  • readBlock告訴POP當前的屬性值

  • writeBlock中修改變化後的屬性值

  • threashold決定了動畫變化間隔的阈值,值越大writeBlock的調用次數越少

POPAnimatableProperty其實是POP中一個比較重要的東西,像上面提到的POP自帶的動畫屬性,查看源代碼可以看到也只是POP自動幫你設置好了POPAnimatableProperty而已,其作用就是當動畫的某個時間片被觸發時,告訴系統如何根據當前時間片做出變化。

還是以一個實際的例子來說明如何使用自定義屬性,比如我們要實現一個像系統的時鐘APP裡秒表計時的一個效果。

    POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"countdown" initializer:^(POPMutableAnimatableProperty *prop) {
        prop.writeBlock = ^(id obj, const CGFloat values[]) {
            UILabel *lable = (UILabel*)obj;
            label.text = [NSString stringWithFormat:@"d:d:d",(int)values[0]/60,(int)values[0]%60,(int)(values[0]*100)0];
        };
//        prop.threshold = 0.01f;
    }];
    POPBasicAnimation *anBasic = [POPBasicAnimation linearAnimation];   //秒表當然必須是線性的時間函數
    anBasic.property = prop;    //自定義屬性
    anBasic.fromValue = @(0);   //從0開始
    anBasic.toValue = @(3*60);  //180秒
    anBasic.duration = 3*60;    //持續3分鐘
    anBasic.beginTime = CACurrentMediaTime() + 1.0f;    //延遲1秒開始
    [label pop_addAnimation:anBasic forKey:@"countdown"];

其動畫效果如下

2015-03-11-intro-pop-44.gif

有沒有從中得到一些啟發呢? POP可以做的事情可遠比Core Animation要多(注意這裡我們使用了beginTime這個屬性來設置動畫的延遲施放) 例如音樂播放時那種淡入淡出的效果等等也可以用POP來實現

小結

其實只需要熟練掌握POP自帶的三種動畫,即可完成大部分的動畫效果。如果實在是無法滿足你的需求的話,自定義動畫也基本可以滿足你的要求。可以說POP化繁為簡的出現,極大的方便了我們這些苦逼的coder。

當然,就像我說的,POP不僅僅是一個動畫引擎。相信經過我最後一個例子,大家可以得到一點啟示,POP能做的事情還不少 :)

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved