会员升级的动画根据设计提供的UI,为了减小图片的大小,让设计把动画分为了两部分,第一部分为连续的47张图片利用UIImage的animationImages进行播放,第二部分的无限旋转和缩放则用CABasicAnimation实现。
播放png动画,首先要获取图片,说到图片获取的方法,就得看API文档。
UIImage生成实例的方法有:
-
1)imageNamed
从指定文件返回对象。 这个方法有个比较特殊的地方:该方法首先从系统缓存中寻找该图片,如果有,则从缓存中获取;如果没有,则获取图片,再把图片加入缓存;
-
2)imageWithContentFile
从指定文件路径中加载对象并返回。但是该方法不会缓存对象。
-
3)imageWithData
根据NSData返回对象实例
我们不需要缓存图片对象,如果缓存了,内存会暴增。所以我们选择imageWithContentFile这个方法来加载图片
- (void)levelupAnimationWith:(NSString *)level
{
level = [level lowercaseString];//改成小写
NSMutableArray * imageArray = [NSMutableArray array];
for (NSInteger i = 0; i <= levelupImageCount; i++) {
NSString * imagePath = [self getBundleImagePathWith:level num:i];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
[imageArray addObject:image];
}
//最后一张图片
self.lastImagePath = [self getBundleImagePathWith:level num:levelupImageCount];
//图片播放一次所需时长
_levelupImageView.animationDuration = animiationTime;
//图片播放次数,1
_levelupImageView.animationRepeatCount = 1;
//设置动画图片数组
_levelupImageView.animationImages = imageArray;
[_levelupImageView startAnimating];
[self performSelector:@selector(endAinimation) withObject:nil afterDelay:animiationTime];
//添加到window上
if(self.superview == nil){
self.alpha = 0.;
[[LJBHSLevelupView mainWindow] addSubview:self];
[UIView animateWithDuration:0.25 animations:^{
self.alpha = 1.;
} completion:^(BOOL finished) {
}];
}
}
//拼接Bundle path
- (NSString *) getBundleImagePathWith:(NSString *)level num:(NSInteger)num
{
NSString *levelBundle = [[NSBundle mainBundle] pathForResource:@"levelup" ofType:@"bundle"];
NSString * levelupPrefix = [NSString stringWithFormat:@"levelup_%@",level];
NSString * imageName = [NSString stringWithFormat:@"%@_%02ld@2x",levelupPrefix,(long)num];
NSString * imagePath = [[NSBundle bundleWithPath:levelBundle] pathForResource:imageName ofType:@"png" inDirectory:levelupPrefix];
return imagePath;
}
- (void)endAinimation
{
[_levelupImageView stopAnimating];
_levelupImageView.animationImages = nil;
[_levelupImageView setImage:[UIImage imageWithContentsOfFile:self.lastImagePath]];
_cancelBtn.hidden = NO;
_rotateImageView.hidden = NO;
_shareBtn.hidden = NO;
[self addRotationAnimation];
[self addZoomAnimation];
}
/*************旋转动画*************/
-(void)addRotationAnimation
{
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI*2.0];
rotationAnimation.duration = 6.0f;//动画时间
rotationAnimation.repeatCount = HUGE_VALF;//设置重复次数,HUGE_VALF可看做无穷大,起到循环动画的效果
[_rotateImageView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
/*************缩放动画*************/
-(void)addZoomAnimation
{
CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue=[NSNumber numberWithFloat:1.1];
animation.toValue=[NSNumber numberWithFloat:0.6];
animation.duration=1.0f;//动画时间
animation.autoreverses=YES;//设置这个属性表示完成动画后会回到执行动画之前的状态
animation.repeatCount=HUGE_VALF;//设置重复次数,HUGE_VALF可看做无穷大,起到循环动画的效果
[_rotateImageView.layer addAnimation:animation forKey:@"zoomAnimation"];
}
CABasicAnimation的动画属性和说明
-
@property(nullable, strong) id fromValue; //改变属性的起始值
-
@property(nullable, strong) id toValue;//改变属性的结束值
-
@property(nullable, strong) id byValue; //改变属性相同起始值的改变量
-
@property float repeatCount;//重复的次数。不停重复设置为 HUGE_VALF
-
@property CFTimeInterval repeatDuration;//设置动画的时间。在该时间内动画一直执行,不计次数。
-
@property CFTimeInterval beginTime;//指定动画开始的时间。从开始延迟几秒的话,设置为【CACurrentMediaTime() + 秒数】 的方式
-
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;//设置动画的速度变化
-
@property BOOL autoreverses;//动画结束时是否执行逆动画
防止动画结束后回到初始状态
只需设置removedOnCompletion、fillMode两个属性就可以了。
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
为什么动画结束后返回原状态?
首先我们需要搞明白一点的是,layer动画运行的过程是怎样的?其实在我们给一个视图添加layer动画时,真正移动并不是我们的视图本身,而是 presentation layer 的一个缓存。动画开始时 presentation layer开始移动,原始layer隐藏,动画结束时,presentation layer从屏幕上移除,原始layer显示。这就解释了为什么我们的视图在动画结束后又回到了原来的状态,因为它根本就没动过。
这个同样也可以解释为什么在动画移动过程中,我们为何不能对其进行任何操作。
所以在我们完成layer动画之后,最好将我们的layer属性设置为我们最终状态的属性,然后将presentation layer 移除掉。
网友评论