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
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动画要更加人性化, 更加好用.
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];
}
运行后就能看到非常逼真的动画衰减效果了
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
这里只是测试了一个属性, 可以点进去看它其他的属性, 就不一一演示了