做过一个项目,里面涉及到的动画效果比较多,在这里做个小小的总结。
直线动画效果
实现一个物体在某段时间从一个点移动到另一个点。
效果如下:
动画相关代码如下:
动画模型:
@interface AnimationModel : NSObject
@property(nonatomic,strong) NSArray * images;
@property(nonatomic,assign) float fromX;
@property(nonatomic,assign) float fromY;
@property(nonatomic,assign) float toX;
@property(nonatomic,assign) float toY;
@property(nonatomic,assign) BOOL loop;
@property(nonatomic,assign) float time;
@end
动画实现:
-(void)addSingleLineAnimationToView:(UIView *)view animationModel:(AnimationModel *)model{
CABasicAnimation* moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(model.fromX,model.fromY)];
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(model.toX,model.toY)];
moveAnimation.duration = model.time;
moveAnimation.removedOnCompletion = NO;
moveAnimation.repeatCount = MAXFLOAT;
if (model.loop == 0) {
moveAnimation.repeatCount = 1;
}
[view.layer addAnimation:moveAnimation forKey:@"singleLineAnimation"];
}
爆炸点赞动画效果
效果有点像撒花,效果如下:
这个效果的实现也是我在网上找到的,封装了一个View和一个button,调用很方便,下面我贴一下调用的代码,后面会给出完整代码的地址。
调用代码:
-(BZFireworkAnimationButton *)praiseButton{
if (!_praiseButton) {
_praiseButton = [[BZFireworkAnimationButton alloc] initWithFrame:CGRectMake(150, 200, 50, 50)];
_praiseButton.particleImage = [UIImage imageNamed:@"button_bulletin_board_collected"];
_praiseButton.particleScale = 0.05f;
_praiseButton.particleScaleRange = 0.02f;
[_praiseButton addTarget:self action:@selector(praiseAction:) forControlEvents:UIControlEventTouchUpInside];
[_praiseButton setImage:[UIImage imageNamed:@"button_bulletin_board_uncollect"] forState:UIControlStateNormal];
[_praiseButton setImage:[UIImage imageNamed:@"button_bulletin_board_collected"] forState:UIControlStateSelected];
}
return _praiseButton;
}
-(void)praiseAction:(BZFireworkAnimationButton *)button{
if (button.selected) {
[button popInsideWithDuration:0.4f];
}else{
[button popOutsideWithDuration:0.4];
[button animate];
}
button.selected = !button.selected;
}
心跳(放大缩小)动画效果
效果如下:
实现代码:
-(void)setupHeartbeatAnimationInView:(UIView *)view{
// 设定为缩放
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
// 动画选项设定
animation.duration = 1.2; // 动画持续时间
animation.repeatCount = 10000000000; // 重复次数
animation.autoreverses = YES; // 动画结束时执行逆动画
// 缩放倍数
animation.fromValue = [NSNumber numberWithFloat:1.0]; // 开始时的倍率
animation.toValue = [NSNumber numberWithFloat:1.4]; // 结束时的倍率
animation.removedOnCompletion = NO;
// 添加动画
[view .layer addAnimation:animation forKey:@"scale-layer"];
}
上下浮动效果
效果如下:
代码实现如下:
@interface FloatViewController ()
//判断是否是当前ViewController,如果不是,则停止动画,否则动画一直在,且dealloc方法不会被调用
@property(nonatomic,assign) BOOL isCurrentVC;
@end
@implementation FloatViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor orangeColor];
UIImageView * animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(30, 105, 144, 350)];
animationImageView.image = [UIImage imageNamed:@"image_city_angel_login_girl"];
[self setAnimationImageViewAnimation:animationImageView];
[self.view addSubview:animationImageView];
}
-(void)dealloc{
NSLog(@"FloatViewController dealloc");
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.isCurrentVC = YES;
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.isCurrentVC = NO;
}
-(void)setAnimationImageViewAnimation:(UIImageView *)animationImageView{
[UIView animateWithDuration:1 animations:^{
animationImageView.frame = CGRectMake(30, 90, 144, 350);
}];
[UIView animateWithDuration:1 delay:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
animationImageView.frame = CGRectMake(30, 105, 144,350);
} completion:^(BOOL finished) {
if (self.isCurrentVC) {
[self setAnimationImageViewAnimation:animationImageView];
}
}];
}
这个动画效果有一点需要注意的就是需要手动停止,最好离开该页面的时候就手动让它停止,否则会造成内存泄漏。如果是push到下级页面,手动停止了动画,回到该页面时还需要动画启动的话,可以给动画的view一个tag值,然后在viewWillAppear中调用一下setAnimationImageViewAnimation方法。
图片序列gif效果
开发中经常遇到动图的效果,如果美术给的是gif图,那么可以使用SDWebImage中的方法进行播放,如果给的是图片序列,我们可以用UIImageView自带的属性来实现。
效果如下:
使用UIImageView自带属性实现代码如下:
NSArray * images = @[@"gif_ferriswheel1",@"gif_ferriswheel2",@"gif_ferriswheel3",@"gif_ferriswheel4",@"gif_ferriswheel5",@"gif_ferriswheel6"];
UIImageView * imageViews = [[UIImageView alloc] init];
UIImage * image = [UIImage imageNamed:images[0]];
imageViews.frame = CGRectMake(120, 200, image.size.width, image.size.height);
NSMutableArray * imagesArray = [NSMutableArray array];
for (NSString * imagesName in images) {
UIImage * tempImage = [UIImage imageNamed:imagesName];
[imagesArray addObject:tempImage];
}
imageViews.animationImages = [imagesArray copy];
imageViews.animationDuration = 0.9;
imageViews.animationRepeatCount = 1000000000;
[imageViews startAnimating];
[self.view addSubview:imageViews];
这种方式需要注意的是animationImages这个数组里面的对象是UIImage,所以千万不要把图片名称的数组直接赋值,会造成崩溃。
直线+Gif效果
图片既有位移的改变,又在改变位移的同时自身在变,比如一个人走路。
效果如图:
实现动画主要代码如下:
-(void)initData{
NSString * jsonPath = [[NSBundle mainBundle] pathForResource:@"animation" ofType:@"json"];
NSData * data = [NSData dataWithContentsOfFile:jsonPath];
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSArray * lineGifArray = dic[@"walk_animation"];
self.lineGifArray = [NSMutableArray array];
for (NSDictionary * item in lineGifArray) {
AnimationModel * model = [[AnimationModel alloc] init];
[model setValuesForKeysWithDictionary:item];
[self.lineGifArray addObject:model];
}
}
-(void)setupLineGifAnimation{
for (AnimationModel * model in self.lineGifArray) {
UIImageView * animationImageView = [[UIImageView alloc] init];
animationImageView.image = [UIImage imageNamed:model.images[0]];
animationImageView.frame = CGRectMake(model.toX, model.toY, animationImageView.image.size.width, animationImageView.image.size.height);
NSMutableArray * imagesArray = [NSMutableArray array];
for (NSString * imagesName in model.images) {
UIImage * tempImage = [UIImage imageNamed:imagesName];
[imagesArray addObject:tempImage];
}
animationImageView.animationImages = [imagesArray copy];
animationImageView.animationDuration = 1.2;
animationImageView.animationRepeatCount = 1000000000;
[animationImageView startAnimating];
[self.view addSubview:animationImageView];
[self addSingleLineAnimationToView:animationImageView animationModel:model];
}
}
-(void)addSingleLineAnimationToView:(UIView *)view animationModel:(AnimationModel *)model{
CABasicAnimation* moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(model.fromX,model.fromY)];
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(model.toX,model.toY)];
moveAnimation.duration = model.time;
moveAnimation.removedOnCompletion = NO;
moveAnimation.repeatCount = MAXFLOAT;
if (model.loop == 0) {
moveAnimation.repeatCount = 1;
}
[view.layer addAnimation:moveAnimation forKey:@"lineGifAnimation"];
}
这个动画效果涉及到两个时间,一个位移从起点到终点的时间和一个完成一套动作的时间,这两个时间需要去调才能做出最自然的效果,我这里提供的是思路,两个时间没有花时间去调,请见谅~
动画能让我们的app显得更有生机和活力,也还有很多其他的动画效果,记住的话更好,记不住可以抽时间整理一下,下次再写的时候找起来方便。
这六个动画效果我自己写了一个完整的demo,点击这里获取代码。