POP背后的开发者是 Kimon Tsinteris, Push Pop Press 的联合创始人,曾经在Apple担任高级工程师,并参与了 iPhone 和 iPad 上软件的研发(iPhone的指南针以及地图)。2011年的时候 Facebook 收购了他的公司,此后他便加入了 Facebook 负责 Facebook iOS 版本的开发。
POP 使用 Objective-C++ 编写,Objective-C++ 是对 C++ 的扩展,就像 Objective-C 是 C 的扩展。而至于为什么他们用 Objective-C++ 而不是纯粹的 Objective-C,原因是他们更喜欢 Objective-C++ 的语法特性所提供的便利
POP动画是一个十分受欢迎的动画,在这个框架刚出来一周的时候点赞👍量都超过3k,现在点赞量达到17.8k。身为一个iOS开发者必须对这个框架有一定的了解。
效果图
POP动画应用.gif我在项目中目录
- pop基础介绍
- pop项目中PropertyNamed简单介绍
- 弹性动画
- 弹出小卡片
- 画圆
- 进度条
- 图像折叠
想要看代码的可以点击这里
项目参考了pop-handapp , popping这两个项目,内容也是基于这两个项目写的。
【注意】
在使用pop-handapp
的时候,我们pod
以后会报Cannot initialize a member subobject of type 'NSUInteger' (aka 'unsigned long') with an rvalue of type 'nullptr_t'
这个错误,解决办法,我先把POP
库移除,然后随便添加一个AFNetworking
库,然后在添加POP
库,为啥这样做,我也不知道哦,反正我是这样解决问题的。
参考文献
Facebook POP动效库使用教程
Facebook Pop 使用指南
Facebook POP 进阶指南
基本类型
POP基础.png使用之前需要先倒入#import <POP.h>
POPBasicAnimation
基础使用
/*
设置动画至少需要三步
1、定义一个animation对象 并指定对应的动画属性
2、设置初始值和默认值(初始值可以不指定 会默认从当前值开始)
3、添加到想产生动画的对象上
POPBasicAnimation可配置的属性与默认值为
duration:0.4 //动画间隔
*/
POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionX];
animation.toValue = @(_BaseView.center.y + 200);
animation.beginTime = CACurrentMediaTime() + 1.0f;
[_BaseView pop_addAnimation:animation forKey:@"BasicAnimation"];
我们点击进入POPBasicAnimation
里面
-
两个初始化方法
-
+ (instancetype)animation;
-
+ (instancetype)animationWithPropertyNamed
-
四个动画方式
-
kCAMediaTimingFunctionLinear
-
kCAMediaTimingFunctionEaseIn
-
kCAMediaTimingFunctionEaseOut
-
kCAMediaTimingFunctionEaseInEaseOut
-
两个属性
-
duration
-
timingFunction
POPSpringAnimation
POPSpringAnimation也许是大多数人使用POP的理由 其提供一个类似弹簧一般的动画效果
POPSpringAnimation可配置的属性与默认值为
-
springBounciness //[0-20] 弹力 越大则震动幅度越大
-
springSpeed //[0-20] 速度 越大则动画结束越快
-
dynamicsTension //拉力 接下来这三个都跟物理力学模拟相关 数值调整起来也很费时 没事不建议使用哈
-
dynamicsFriction //摩擦 同上
-
dynamicsMass //质量 同上
【注意】
POPSpringAnimation是没有duration字段的 其动画持续时间由以上几个参数决定
简单实用
POPSpringAnimation *aniSpring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
aniSpring.toValue = @(_BaseView.center.x + 100);
aniSpring.beginTime = CACurrentMediaTime();
aniSpring.springBounciness = 10.0;
[_BaseView pop_addAnimation:aniSpring forKey:@"POPSpringAnimation"];
POPDecayAnimation
Decay Animation 就是 POP 提供的另外一个非常特别的动画,他实现了一个衰减的效果。这个动画有一个重要的参数 velocity(速率),一般并不用于物体的自发动画,而是与用户的交互共生
Decay 的动画没有 toValue 只有 fromValue,然后按照 velocity 来做衰减操作
想要理解更深POPDecayAnimation
,可以参考小球碰壁反弹效果
代码
#import "DecayAnimationTwo.h"
#import <POP.h>
@interface DecayAnimationTwo ()<POPAnimationDelegate>
@property (nonatomic,strong) UIView *baseView;
@end
@implementation DecayAnimationTwo
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"碰壁反弹效果";
_baseView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
_baseView.center = self.view.center;
_baseView.layer.masksToBounds = YES;
_baseView.layer.cornerRadius = _baseView.bounds.size.width/2;
_baseView.backgroundColor = [UIColor redColor];
[self.view addSubview:_baseView];
//拖拽手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(PanGesture:)];
[_baseView addGestureRecognizer:pan];
}
//拖拽手势
- (void)PanGesture:(UIPanGestureRecognizer*)pan{
//在拖动过程中
//取出偏移量
CGPoint offset = [pan translationInView:self.view];
//让baseView平移
_baseView.transform = CGAffineTransformTranslate(_baseView.transform, offset.x, offset.y);
//平移完之后将偏移量重新置为0
//这很重要,要记住
[pan setTranslation:CGPointZero inView:self.view];
//当拖动手势结束的时候,开始动画
if (pan.state == UIGestureRecognizerStateEnded) {
POPDecayAnimation *decayAnimation = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition];
CGPoint velocity = [pan velocityInView:self.view];
decayAnimation.velocity = [NSValue valueWithCGPoint:velocity];
[_baseView.layer pop_addAnimation:decayAnimation forKey:@"layerPositionAnimation"];
decayAnimation.delegate = self;
}
}
#pragma mark - POPAnimationDelegate
///在小球弹动的过程中判断是否碰壁
- (void)pop_animationDidApply:(POPDecayAnimation *)anim
{
BOOL baseViewInsideOfSuperView = CGRectContainsRect(self.view.frame, self.baseView.frame);
if (!baseViewInsideOfSuperView) {
CGPoint currentVelocity = [anim.velocity CGPointValue];
CGPoint velocity = CGPointMake(currentVelocity.x, -currentVelocity.y);
POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPosition];
positionAnimation.velocity = [NSValue valueWithCGPoint:velocity];
positionAnimation.toValue = [NSValue valueWithCGPoint:self.view.center];
[self.baseView.layer pop_addAnimation:positionAnimation forKey:@"layerPositionAnimation"];
}
}
@end
POPAnimatableProperty
效果图
POPAnimatableProperty.gif
代码
/*
其组成就是一个readBlock一个writeBlock和一个threashold
readBlock告诉POP当前的属性值
writeBlock中修改变化后的属性值
threashold决定了动画变化间隔的阈值 值越大writeBlock的调用次数越少
*/
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100)];
label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label];
POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"countdown" initializer:^(POPMutableAnimatableProperty *prop) {
prop.readBlock = ^(id obj, CGFloat values[]) {
};
prop.writeBlock = ^(id obj, const CGFloat values[]) {
UILabel *label = (UILabel*)obj;
label.text = [NSString stringWithFormat:@"%02d:%02d:%02d",(int)values[0]/60,(int)values[0]%60,(int)(values[0]*100)%100];
};
prop.threshold = 0.01;
}];
POPBasicAnimation *anBasic = [POPBasicAnimation linearAnimation]; //秒表当然必须是线性的时间函数
anBasic.property = prop; //自定义属性
anBasic.fromValue = @(0); //从0开始
anBasic.toValue = @(3*60); //180秒
anBasic.duration = 3*60; //持续3分钟
anBasic.beginTime = CACurrentMediaTime();
[label pop_addAnimation:anBasic forKey:@"countdown"];
PropertyNamed
一些人可能对PropertyNamed
的一些属性不太了解,我这里做了一个简单的demo,对一些简单的属性做了一些解释。
效果图
PropertyNamed.gif譬如kPOPViewCenter
POPBasicAnimation *basicAnimation = [POPBasicAnimation animation];
basicAnimation.property = [POPAnimatableProperty propertyWithName:kPOPViewCenter];
basicAnimation.toValue=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
[_baseView pop_addAnimation:basicAnimation forKey:@"kPOPViewCenter"];
具体代码请参考这里,也可以参考详解Fecebook PoP API 及 属性使用!这篇文章,来对属性进行补充
网友评论