1. 程式人生 > >iOS中Facebook開源動畫庫POP的簡單使用

iOS中Facebook開源動畫庫POP的簡單使用

POP動畫簡介

1.POP動畫引擎是Facebook公司開源的
2.POP動畫引擎主要實現了真實物理系的動畫效果(彈簧效果與衰減效果)
3.POP動畫引擎的動畫效果非常流暢, 因為它使用了CADisplayLink來重新整理畫面(每秒60幀, 接近遊戲開發引擎)
4.POP動畫引擎自成體系, 與系統的CoreAnimation有著很大的區別, 但使用非常類似

測試程式碼


#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) CADisplayLink *displayLink;
@property
(nonatomic, assign) NSInteger count; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkEvent:)]; [self performSelector:@selector(eventOne) withObject:self afterDelay:1
]; [self performSelector:@selector(eventTwo) withObject:self afterDelay:2]; } - (void)displayLinkEvent:(id)object{ self.count ++; NSLog(@"count = %ld", self.count); } - (void)eventOne{ [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } - (void
)eventTwo{ [self.displayLink invalidate]; } @end

POP動畫引擎中Layer與CALayer的聯絡與區別

1.使用POP動畫與使用CALayer動畫非常相似
2.POP動畫的執行沒有中間狀態
3.POP動畫是對CALayer動畫的補充, 但不能實現所有的CALayer的動畫效果
4.POP動畫可以作用在任何物件上, 不僅僅是CALayer

下面我們用一個demo來說明, 首先我們新建一個工程POPLayer, 在工程裡先用cocoapods匯入POP庫, 如果你沒用過cocoapods, 可以上github手動下載POP庫, 手動匯入, 當然也可以安裝cocoapods. 匯入POP庫後, 我們在工程的viewDidLoad裡寫如下程式碼:


#import "ViewController.h"
#import <POP.h>

@interface ViewController ()

@property (nonatomic, strong) CALayer *normalLayer;
@property (nonatomic, strong) CALayer *popLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 處理normalLayer
//    [self accessNormalLayer]; // CALayer動畫移除後會突然出現在終點位置

    // 處理POPLayer
    [self accessPOPLayer];  // 我們發現即使POP動畫移除了也會顯示在當前位置
}

#pragma mark --- 處理POPLayer
- (void)accessPOPLayer{

    // 初始化POPLayer
    self.popLayer = [CALayer layer];
    self.popLayer.frame = CGRectMake(100, 100, 100, 100);
    self.popLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.popLayer];

    // 初始化POP動畫
    POPBasicAnimation *popAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPosition];
    popAnimation.toValue = [NSValue valueWithCGPoint:(CGPointMake(100 + 50, 400))];
    popAnimation.duration = 4.f;
    popAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    // 新增動畫
    [self.popLayer pop_addAnimation:popAnimation forKey:nil];

    // 1.5s後移除
    [self performSelector:@selector(removePopAnimation) withObject:nil afterDelay:1.5];
}
- (void)removePopAnimation{

    [self.popLayer pop_removeAllAnimations];
}


#pragma mark --- 處理normalLayer
- (void)accessNormalLayer{

    // 初始化Layer
    self.normalLayer = [CALayer layer];
    self.normalLayer.frame = CGRectMake(100, 100, 100, 100);
    self.normalLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.normalLayer];

    // 初始化動畫
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    basicAnimation.fromValue = [NSValue valueWithCGPoint:self.normalLayer.position];
    basicAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(100 + 50, 400)];
    basicAnimation.duration = 4.f;
    basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    // 設定結束位置的值
    self.normalLayer.position = CGPointMake(100 + 50, 400);

    // 開始動畫
    [self.normalLayer addAnimation:basicAnimation forKey:nil];

    // 1.5秒後移除動畫
    [self performSelector:@selector(removeNormalAnimation) withObject:nil afterDelay:1.5];

}

- (void)removeNormalAnimation{

    CALayer *layer = self.normalLayer.presentationLayer;
    NSLog(@"%@", NSStringFromCGRect(layer.frame));
    NSLog(@"%@", NSStringFromCGRect(self.normalLayer.frame));
    [self.normalLayer removeAllAnimations];
}
@end

我們對CALayer動畫和POP動畫進行比較, 結果最後得出POP動畫要更加人性化, 更加好用.

用POP動畫引擎實現衰減動畫

1.衰減動畫由POPDecayAnimation來實現
2.需要精確計算停止運動瞬間的加速度才能夠用衰減動畫做出真實的效果
下面我們上程式碼, 因為在工程裡我是用CocoaPods匯入的POP庫, 所以如果你沒有安裝的話直接手動新增就好了


#import "ViewController.h"
#import <POP.h>


@interface ViewController ()

@property (nonatomic, strong) UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 初始化UIButton
    self.button = [UIButton buttonWithType:(UIButtonTypeSystem)];
    self.button.frame = CGRectMake(0, 0, 100, 100);
    self.button.backgroundColor = [UIColor redColor];
    self.button.layer.cornerRadius = 50;
    self.button.layer.masksToBounds = YES;
    self.button.center = self.view.center;
    [self.view addSubview:self.button];

    [self.button addTarget:self action:@selector(buttonEvent:) forControlEvents:(UIControlEventTouchUpInside)];

    // 初始化手勢
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(hanlePanGesture:)];
    // 新增手勢
    [self.button addGestureRecognizer:panGesture];
}

- (void)hanlePanGesture:(UIPanGestureRecognizer *)recognizer{

    // 獲取定位點
    CGPoint translation = [recognizer translationInView:self.view];
    // recognizer.view.center指的就是button的center,手勢已經新增到UIButton上
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);

    // 恢復座標系
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

    // 動畫停止瞬間獲取加速度
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        // 獲取加速度值
        CGPoint velocity = [recognizer velocityInView:self.view];
        // 初始化POP的decay(衰減動畫)
        POPDecayAnimation *decayAnimation = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition];
        decayAnimation.velocity = [NSValue valueWithCGPoint:velocity];
        [recognizer.view.layer pop_addAnimation:decayAnimation forKey:nil];
    }
}


- (void)buttonEvent:(UIButton *)button{

    [button.layer pop_removeAllAnimations];
}

執行後就能看到非常逼真的動畫衰減效果了

用POP動畫引擎實現彈簧動畫

1.彈簧動畫由POPSpringAnimation來實現
2.彈簧的質量速度時間等值都是可以設定的
下面上程式碼, 還是一樣要先匯入POP庫


#import "ViewController.h"
#import <POP.h>

@interface ViewController ()

@property (nonatomic, strong) UIView *showView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 設定控制器的背景色
    self.view.backgroundColor = [UIColor blackColor];

    // 初始化View
    self.showView = [[UIView alloc] initWithFrame:(CGRectMake(0, 0, 50, 50))];
    self.showView.backgroundColor = [UIColor cyanColor];
    self.showView.center = self.view.center;
    [self.view addSubview:self.showView];

    // 延遲1秒執行
    [self performSelector:@selector(startSpringAnimation) withObject:nil afterDelay:1.f];
}

- (void)startSpringAnimation{

    // 初始化Spring動畫
    POPSpringAnimation *sizeAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds];
    sizeAnimation.springSpeed = 0.f;

    sizeAnimation.toValue = [NSValue valueWithCGRect:(CGRectMake(0, 0, 200, 200))];

    // 新增動畫
    [self.showView pop_addAnimation:sizeAnimation forKey:nil];
}

@end

這裡只是測試了一個屬性, 可以點進去看它其他的屬性, 就不一一演示了