CoreAnimation詳解(二)從UIKit的角度來詳細闡述,coreanimationuikit
原創Blog,轉載請註明出處
blog.csdn.net/hello_hwc
UIKit是在Cocoa Touch層的,其底層仍然是通過Core Animation實現的,因此我把所有的動畫講解都放到了CoreAnimation這一塊,
通常簡單的動畫用UIKit來實現足矣,當然,用Layer可以實現更加複雜的動畫。不瞭解Layer的同學可以看看我前一篇文章。
本文將要講述的內容:
1 可以用作Animation的屬性
2 用基於block的方法來實現動畫
3 用Begin/Commit方法來實現動畫
4 View之間切換的動畫
5 多個動畫一起組成複雜的動畫
6 View和Layer動畫進行組合
還是老樣子,我還是會寫一個Demo,這個demo是基於一個tabbarViewController的,每個部分展示兩個動畫。下載連結附在最後。下面開始本文
視頻的Demo連結(以防gif不會動)
http://v.youku.com/v_show/id_XODgzNDU3MDI0.html
一 可以用作Animation的屬性
從UIKit的角度,動畫是從UIView的屬性變更來實現的。可以變換的屬性如下
frame |
確定view在superview的位置和大小,這裡要注意,如果View的屬性transform不是恒定的,修改位置和大小用bounds和center來修改。(其實一般修改位置和大小都不直接修改frame) |
bounds |
確定view的大小 |
center |
確定view的中心在superview的位置 |
transform |
2D仿射變換(scale,rotate,translate)3D變換要用到CALayer的Animation |
alpha |
透明度 |
backgroundColor |
背景色 |
contentStretch |
修改View展開來填充可以利用空間的方式 |
二 基於Block的方法
主要就是三個類方法,在動畫的時候是在另一個線程上的,不會組賽主線程。
animateWithDuration:animationsanimateWithDuration:animations:completion:animateWithDuration:delay:options:animations:completion
簡單介紹下各個參數:
[UIView animateWithDuration: //動畫期間 delay: //延遲多久執行 options://執行選項:例如動畫的流程說明,動畫過程是否允許互動等等,比較多,更多參見文檔 animations:^{ //執行的動畫的block } completion:^(BOOL finished) { //動畫結束後的block }];
然後,定義一個動畫,讓imageview運動到中心,放大到之前的2倍,並且透明度變味0.5,結束後恢複原樣。
效果如下gif。
實現代碼,
CGPoint oldCenter = self.imageivew.center; CGAffineTransform oldtransform = self.imageivew.transform; CGFloat oldAlpha = self.imageivew.alpha; [UIView animateWithDuration:2.0 //動畫期間 delay:0.0 //延遲多久執行 options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState //執行選項:例如動畫的流程說明,動畫過程是否允許互動等等,比較多,更多參見文檔 animations:^{ //執行的動畫的block self.imageivew.center = self.view.center; self.imageivew.transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(M_PI), CGAffineTransformMakeScale(2.0, 2.0)); self.imageivew.alpha = 0.5; } completion:^(BOOL finished) { //動畫結束後的block self.imageivew.center = oldCenter; self.imageivew.transform = oldtransform; self.imageivew.alpha = oldAlpha; }];
三 基於Begin/commit的方式
也是UIView的類方法來配置,動畫在另一個線程上執行,不會阻塞主線程。
幾個方法
setAnimationStartDate: setAnimationDelay: |
配置動畫開始執行的時間 |
setAnimationDuration: |
執行時間 |
setAnimationCurve: |
動畫執行的加速減速過程 |
setAnimationRepeatCount: setAnimationRepeatAutoreverses: |
設定重複次數以及是否自動返回 |
setAnimationDelegate: setAnimationWillStartSelector: setAnimationDidStopSelector: |
用代理或者是Selector來監聽動畫開始結束事件 |
一個例子
效果和之前的類似,但是這次會逆向返回,執行1.5次
注意:這裡我把大部分方法的使用方式都列上去了,正常情況下是不需要配置這麼多的。
實現代碼
- (IBAction)animate2:(id)sender { [UIView beginAnimations:@"Animate 2" context:nil]; //配置動畫的執行屬性 [UIView setAnimationDelay:0.5];//延遲時間 [UIView setAnimationDelegate:self]; [UIView setAnimationWillStartSelector:@selector(willStart)];//監聽開始的事件 [UIView setAnimationDidStopSelector:@selector(didStop)];//監聽結束的事件 [UIView setAnimationDuration:2.0];//執行時間 [UIView setAnimationRepeatAutoreverses:YES];//自動複原 [UIView setAnimationRepeatCount:1.5];//重複次數 [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];//執行的加速過程(加速開始,減速結束) [UIView setAnimationBeginsFromCurrentState:YES];//是否由當前動畫狀態開始執行(處理同一個控制項上一次動畫還沒有結束,這次動畫就要開始的情況) //實際執行的動畫 self.imageivew.center = self.view.center; self.imageivew.transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(M_PI), CGAffineTransformMakeScale(2.0, 2.0)); self.imageivew.alpha = 0.5; //提交動畫 [UIView commitAnimations];}-(void)willStart{ NSLog(@"will start");}//這個有點問題-(void)didStop{ NSLog(@"did stop");}
四 View之間的切換動畫
比如添加刪除subview的時候,比如讓一個subview隱藏另一個顯示的時候,加上切換動畫能防止突變,造成使用者困惑。
通常在view之間切換的時候,只是改變hidden以及remove或者add,這樣的好處是系統會進行快照,來產生一副bitmap,佔用資源較少。如果想要同時添加其他動畫,要在函數的options裡添加UIViewAnimationOptionAllowAnimatedContent
4.1 改變一個View的subview
有兩種方式,通過block和通過begin/commit都可以實現。Demo實現的是兩個不同動畫,可以看到containView的不同,動畫的差異。
動畫一
用Flip的方式進行切換
效果
實現代碼
[UIView beginAnimations:@"AnimateInContainView" context:nil]; [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.containVIew cache:YES]; [UIView setAnimationDuration:1.0]; self.firstImageView.hidden = !self.firstImageView.hidden; self.secondImageView.hidden = !self.secondImageView.hidden;
動畫二效果
用翻頁的效果進行實現
實現代碼
[UIView transitionWithView:self.view duration:1.0 options:UIViewAnimationOptionTransitionCurlUp animations:^{ self.firstImageView.hidden = !self.firstImageView.hidden; self.secondImageView.hidden = !self.secondImageView.hidden; } completion:^(BOOL finished) { }];
4.2 將一個View替代為一個新的view transitionFromView:toView:duration:options:completion:
這個函數會用toView來替換FrameView,FromView會被刪除,如果只是想隱藏,要為options添加 UIViewAnimationOptionShowHideTransitionViews。
實現效果:
如果第一個imageView存在,則用第二個替換,反之亦然
代碼:
[UIView transitionFromView:(self.isFirstViewSHowing ? self.firstView : self.secondView) toView:(self.isFirstViewSHowing ? self.secondView : self.firstView) duration:1.0 options:(self.isFirstViewSHowing ? UIViewAnimationOptionTransitionFlipFromRight : UIViewAnimationOptionTransitionFlipFromLeft) completion:^(BOOL finished) { if (finished) { self.isFirstViewSHowing = !self.isFirstViewSHowing; } }];
五 動畫組合
不管是用block還是begin/commit的方式,都可以監聽動畫結束的事件,那麼一個動畫結束的事件裡開始另一個動畫,動畫就組合到一起了。
實現效果
初始狀態:縮小到之前的0.2倍,完全透明
動畫一:恢複正常大小,變成不透明
動畫二:延遲2s,然後從左向右移除view
動畫
[self.view addSubview:self.firstView]; self.firstView.center = self.view.center; self.firstView.transform = CGAffineTransformMakeScale(0.2,0.2); self.firstView.alpha = 0.0; self.animation6button.enabled = NO; [UIView animateWithDuration:1.0 animations:^{ self.firstView.transform = CGAffineTransformMakeScale(1.0, 1.0); self.firstView.alpha = 1.0; } completion:^(BOOL finished) { if (finished) { [UIView animateWithDuration:1.0 delay:2.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ self.firstView.center = CGPointMake(self.firstView.center.x + CGRectGetWidth(self.view.frame), self.firstView.center.y); } completion:^(BOOL finished) { [self.firstView removeFromSuperview]; self.animation6button.enabled = YES; }]; } }];
六 同CALayer的動畫配合
不管是從UIkit還是從Layer的角度,底層都是Core Animation實現的,因此只要兩個動畫幾乎同時提交的,那麼動畫的過程就是同時執行的。
實現效果
動畫一:在layer的角度進行3D旋轉,同時在view的角度把透明度變成0.2
動畫二:用翻頁的方式刪除ImageView
代碼
[self.view addSubview:self.secondView]; self.secondView.center = self.view.center; CABasicAnimation* layerAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; layerAnimation.duration = 2.0; layerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; layerAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI,1,1,1)]; layerAnimation.removedOnCompletion = NO; layerAnimation.fillMode = kCAFillModeForwards; [self.secondView.layer addAnimation:layerAnimation forKey:@"layerAnimation"]; [UIView animateWithDuration:2.0 animations:^{ self.secondView.alpha = 0.2; } completion:^(BOOL finished) { [UIView transitionFromView:self.secondView toView:nil duration:1.0 options:UIViewAnimationOptionTransitionCurlUp completion:^(BOOL finished) { self.secondView = nil; }]; }];
最後,附上Demo的下載連結
CSDN下載:
http://download.csdn.net/detail/hello_hwc/8412927