iOS幾種動畫效果的實現
做過一個專案,裡面涉及到的動畫效果比較多,在這裡做個小小的總結。
直線動畫效果
實現一個物體在某段時間從一個點移動到另一個點。
效果如下:
動畫相關程式碼如下:
動畫模型:
@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,點選這裡或者這裡獲取程式碼。