iOS的動畫效果一直都很棒很,給人的感覺就是很炫酷很流暢,起到增強用戶體驗的作用。在APP開發中實現動畫效果有很多種方式,對于簡單的應用場景,我們可以使用UIKit提供的動畫來實現。
UIView動畫
UIView動畫實質上是對CoreAnimation的封裝,iOS4.0以后,增加了Block動畫塊,提供更簡潔的方式來實現動畫。
共有六個常見的Block動畫方法:
1、最簡單的Block動畫,包含時間和動畫
[UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^(void)animations#>];
2、帶有動畫完成回調的Block動畫
[UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>];
3、可設置延遲時間和過渡效果的Block動畫 ``[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]
4、Spring動畫,iOS7.0后新增Spring動畫(iOS系統動畫大部分采用SpringAnimation,適用于所有可被添加動畫效果的屬性)
[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> usingSpringWithDamping:<#(CGFloat)#> initialSpringVelocity:<#(CGFloat)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]
5、Keyframes動畫,iOS7.0后新增關鍵幀動畫,支持屬性關鍵幀,不支持路徑關鍵幀
[UIView animateKeyframesWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewKeyframeAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]
-
6、轉場動畫
- 從舊視圖轉到新視圖的動畫效果,在該動畫過程中,fromView會從父視圖中移除,并講toView添加到父視圖中,注意轉場動畫的作用對象是父視圖(過渡效果體現在父視圖上)
[UIView transitionFromView:<#(nonnull UIView *)#> toView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> completion:<#^(BOOL finished)completion#>]
- 從舊視圖轉到新視圖的動畫效果,在該動畫過程中,fromView會從父視圖中移除,并講toView添加到父視圖中,注意轉場動畫的作用對象是父視圖(過渡效果體現在父視圖上)
單個視圖的過渡效果
[UIView transitionWithView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]
UIView動畫可以設置的動畫屬性有
- 1、大小變化(frame)
- 2、拉伸變化(bounds)
- 3、中心位置變化(center)
- 4、旋轉(transform)
- 5、透明度(aipha)
- 6、背景色(backgroundColor)
transform屬性作用:給我們的控件做一些形變,(平移,縮放,旋轉)
移動
// 平移
//每次移動都是相對于上次位置
_redView.transform = CGAffineTransformTranslate(_redView.transform, 100, 0);
//每次移動都是相對于最開始的位置
_redView.transform = CGAffineTransformMakeTranslation(200, 0);
縮放
// sx:寬度縮放的比例 sy:高度縮放的比例
//每次縮放都是相對于最初的大小
_redView.transform = CGAffineTransformMakeScale(0.5, 0.5);
//每次縮放都是相對于上次的大小
_redView.transform = CGAffineTransformScale(_redView.transform, 0.5, 0.5);
旋轉
// 每次旋轉都是相對于最初的角度
_redView.transform = CGAffineTransformMakeRotation(M_PI_4);
//每次旋轉都是相對于現在的角度
_redView.transform = CGAffineTransformRotate(_redView.transform, M_PI_4);
實戰說明
1、最簡潔的Block動畫:包含時間和動畫
代碼
[UIView animateWithDuration:3 animations:^{
//執行動畫
_MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//縮放
_MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋轉
_MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移
}];
效果圖
2、可設置延遲時間和過渡效果的Block動畫
代碼
[UIView animateWithDuration:3 delay:1 options:UIViewAnimationOptionTransitionCurlDown animations:^{
//執行動畫
_MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//縮放
_MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋轉
_MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移
} completion:^(BOOL finished) {
NSLog(@"動畫完成的回調");
}];
UIViewAnimationOptions的枚舉值如下,可組合使用
UIViewAnimationOptionLayoutSubviews//進行動畫時布局子控件
UIViewAnimationOptionAllowUserInteraction//進行動畫時允許用戶交互
UIViewAnimationOptionBeginFromCurrentState//從當前狀態開始動畫
UIViewAnimationOptionRepeat//無限重復執行動畫
UIViewAnimationOptionAutoreverse//執行動畫回路
UIViewAnimationOptionOverrideInheritedDuration//忽略嵌套動畫的執行時間設置
UIViewAnimationOptionOverrideInheritedCurve//忽略嵌套動畫的曲線設置
UIViewAnimationOptionAllowAnimatedContent//轉場:進行動畫時重繪視圖
UIViewAnimationOptionShowHideTransitionViews//轉場:移除(添加和移除圖層的)動畫效果
UIViewAnimationOptionOverrideInheritedOptions//不繼承父動畫設置
UIViewAnimationOptionCurveEaseInOut//時間曲線,慢進慢出(默認值)
UIViewAnimationOptionCurveEaseIn//時間曲線,慢進
UIViewAnimationOptionCurveEaseOut//時間曲線,慢出
UIViewAnimationOptionCurveLinear//時間曲線,勻速
UIViewAnimationOptionTransitionNone//轉場,不使用動畫
UIViewAnimationOptionTransitionFlipFromLeft//轉場,從左向右旋轉翻頁
UIViewAnimationOptionTransitionFlipFromRight//轉場,從右向左旋轉翻頁
UIViewAnimationOptionTransitionCurlUp//轉場,下往上卷曲翻頁
UIViewAnimationOptionTransitionCurlDown//轉場,從上往下卷曲翻頁
UIViewAnimationOptionTransitionCrossDissolve//轉場,交叉消失和出現
UIViewAnimationOptionTransitionFlipFromTop//轉場,從上向下旋轉翻頁
UIViewAnimationOptionTransitionFlipFromBottom//轉場,從下向上旋轉翻頁
3、Spring動畫
usingSpringWithDamping
:震動效果,范圍0~1,數值越小震動效果越明顯
initialSpringVelocity
:初始速度,數值越大初始速度越快
[UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:100 options:UIViewAnimationOptionRepeat animations:^{
//執行動畫
_MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//縮放
_MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋轉
_MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移
} completion:^(BOOL finished) {
}];
效果圖
4、Keyframes動畫
iOS7.0后新增關鍵幀動畫,支持屬性關鍵幀,不支持路徑關鍵幀
options
:動畫的過渡效果
[UIView animateKeyframesWithDuration:0.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
_MyView.backgroundColor = [UIColor blueColor];
} completion:nil];
[UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
_MyView.backgroundColor = [UIColor grayColor];
} completion:nil];
[UIView animateKeyframesWithDuration:1.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
_MyView.backgroundColor = [UIColor greenColor];
} completion:nil];
[UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
_MyView.backgroundColor = [UIColor redColor];
} completion:nil];
UIViewKeyframeAnimationOptions的枚舉值如下,可組合使用:
UIViewAnimationOptionLayoutSubviews//進行動畫時布局子控件
UIViewAnimationOptionAllowUserInteraction//進行動畫時允許用戶交互
UIViewAnimationOptionBeginFromCurrentState//從當前狀態開始動畫
UIViewAnimationOptionRepeat//無限重復執行動畫
UIViewAnimationOptionAutoreverse//執行動畫回路
UIViewAnimationOptionOverrideInheritedDuration//忽略嵌套動畫的執行時間設置
UIViewAnimationOptionOverrideInheritedOptions//不繼承父動畫設置
UIViewKeyframeAnimationOptionCalculationModeLinear//運算模式:連續
UIViewKeyframeAnimationOptionCalculationModeDiscrete//運算模式:離散
UIViewKeyframeAnimationOptionCalculationModePaced//運算模式:均勻執行
UIViewKeyframeAnimationOptionCalculationModeCubic//運算模式:平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced//運算模式:平滑均勻
效果圖
5、轉場動畫
單個視圖的過渡效果
代碼
[UIView transitionWithView:_MyView duration:1 options:UIViewAnimationOptionOverrideInheritedCurve animations:^{
_MyView.backgroundColor = [UIColor greenColor];
} completion:nil];
效果圖
從舊視圖轉到新視圖的動畫效果
[UIView transitionFromView:_MyView toView:_view duration:1 options:UIViewAnimationOptionTransitionFlipFromTop completion:nil];
CAAnimation核心動畫
在iOS的不同圖形層次中都可以寫動畫代碼。越上層,封裝程度越高,動畫實現越簡潔越簡單,但是自由度越低;反之亦然。
如果想要做出更炫的動畫,就必須要了解CAAnimation核心動畫了。
Core Animation結構
基礎動畫(CABasicAnimation)
基礎動畫(CABasicAnimation),通過設定起始點,終點,時間,動畫會沿著你這設定點進行移動。可以看做特殊的CAKeyFrameAnimation
開始之前我們需要先了解一個概念:CALayer
CALayer是個與UIView很類似的概念,同樣有backgroundColor、frame等相似的屬性,我們可以將UIView看做一種特殊的CALayer。但實際上UIView是對CALayer封裝,在CALayer的基礎上再添加交互功能。UIView的顯示必須依賴于CALayer。
我們同樣可以跟新建view一樣新建一個layer,然后添加到某個已有的layer上,同樣可以對layer調整大小、位置、透明度等。
一般來說,layer可以有兩種用途:一是對view相關屬性的設置,包括圓角、陰影、邊框等參數,更詳細的參數請點擊這里;二是實現對view的動畫操控。因此對一個view進行動畫,本質上是對該view的.layer進行動畫操縱。
注意點1:KeyPath中key值的設置
實例化方法
//圍繞y軸旋轉
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
使用方法animationWithKeyPath:
對CABasicAnimation
進行實例化,并指定Layer的屬性作為關鍵路徑進行注冊。
keyPath
決定了基礎動畫的類型,該值不能隨便取,一旦取錯就達不到想要的效果。要改變位置就取position
,要改變透明度就取opacity
,要等比例縮放就取transform.scale
...
一些常用的animationWithKeyPath值的總結
注意點2:fillMode屬性的理解
該屬性定義了你的動畫在開始和結束時的動作。默認值是 kCAFillModeRemoved
fillMode的作用就是決定當前對象過了非active時間段的行為. 非active時間段是指動畫開始之前以及動畫結束之后。如果是一個動畫CAAnimation,則需要將其removedOnCompletion設置為NO,要不然fillMode不起作用
.
kCAFillModeRemoved
這個是默認值,也就是說當動畫開始前和動畫結束后,動畫對layer都沒有影響,動畫結束后,layer會恢復到之前的狀態
kCAFillModeForwards
當動畫結束后,layer會一直保持著動畫最后的狀態
kCAFillModeBackwards
這個和kCAFillModeForwards是相對的,就是在動畫開始前,你只要將動畫加入了一個layer,layer便立即進入動畫的初始狀態。因為有可能出現fromValue不是目前layer的初始狀態的情況,如果fromValue就是layer當前的狀態,則這個參數就沒太大意義。
kCAFillModeBoth
理解了上面兩個,這個就很好理解了,這個其實就是上面兩個的合成.動畫加入后開始之前,layer便處于動畫初始狀態,動畫結束后layer保持動畫最后的狀態.
注意點3
[self.view.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];
我們可以根據這個Key找到這個layer
注意點4:一些常用的屬性
我們做一個心跳的效果
代碼
//初始化CALayer
CALayer *layer = [[CALayer alloc]init];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.frame = CGRectMake(100, 100, 100, 100);
layer.cornerRadius = 10;
[self.view.layer addSublayer:layer];
//配置CABasicAnimation
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
basicAnimation.fromValue = [NSNumber numberWithFloat:1.0];
basicAnimation.toValue = [NSNumber numberWithFloat:1.5];
//當動畫執行到toValue指定的狀態時是從toValue的狀態逆回去,還是直接跳到fromValue的狀態再執行一遍
basicAnimation.autoreverses = YES;
basicAnimation.removedOnCompletion = NO;
basicAnimation.duration = 0.5;
basicAnimation.repeatCount = MAXFLOAT;
//把動畫內容添加到layer上
[layer addAnimation:basicAnimation forKey:@"basicAnimation"];
關鍵幀動畫(CAKeyFrameAnimation)
CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值
屬性介紹
values:就是上述的NSArray對象。里面的元素稱為”關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀
path:可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那么values將被忽略
keyTimes:可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的
value方式代碼
//創建動畫對象
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//設置value
NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 100)];
NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
NSValue *value4=[NSValue valueWithCGPoint:CGPointMake(100, 200)];
NSValue *value5=[NSValue valueWithCGPoint:CGPointMake(100, 300)];
NSValue *value6=[NSValue valueWithCGPoint:CGPointMake(200, 400)];
animation.values=@[value1,value2,value3,value4,value5,value6];
//重復次數 默認為1
animation.repeatCount=MAXFLOAT;
//設置是否原路返回默認為不
animation.autoreverses = YES;
//設置移動速度,越小越快
animation.duration = 4.0f;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
//給這個view加上動畫效果
[_keyFrameView.layer addAnimation:animation forKey:nil];
path方法代碼
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(150, 150)];
[path addLineToPoint:CGPointMake(100, 200)];
[path addLineToPoint:CGPointMake(50, 150)];
anima.path = path.CGPath;
anima.duration = 2.0f;
anima.repeatCount= MAXFLOAT;
anima.autoreverses = NO;
anima.removedOnCompletion = NO;
anima.fillMode = kCAFillModeForwards;
[_keyFrameView.layer addAnimation:anima forKey:@"pathAnimation"];
動畫組動畫(CAAnimationGroup)
動畫組(CAAnimationGroup)是核心動畫中又一個比較重要的知識點。動畫組顧名思義就是一組動畫,它可以將多個動畫對象保存起來,然后再將其添加到layer上,讓組中所有的動畫對象同時并發執行。
/****************** 創建平移動畫 ******************/
CABasicAnimation *basicAnim = [CABasicAnimation animation];
// 設置動畫屬性
basicAnim.keyPath = @"position.y";
basicAnim.toValue = @350;
/****************** 創建縮放動畫 ******************/
CABasicAnimation *scaleAnim = [CABasicAnimation animation];
// 設置動畫屬性
scaleAnim.keyPath = @"transform.scale";
scaleAnim.toValue = @0.5;
;
/****************** 創建動畫組 ******************/
CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
// 將動畫對象都添加到CAAnimationGroup對象中
groupAnim.animations = @[basicAnim, scaleAnim];
/****************** 通過動畫組對象統一設置動畫屬性和狀態 ******************/
// 設置動畫的執行時長
groupAnim.duration = 0.5;
// 動畫完成時保持在最新的狀態
groupAnim.removedOnCompletion = NO;
groupAnim.fillMode = kCAFillModeForwards;
groupAnim.duration = 2.0f;
groupAnim.repeatCount= MAXFLOAT;
groupAnim.autoreverses = YES;
groupAnim.removedOnCompletion = NO;
groupAnim.fillMode = kCAFillModeForwards;
/****************** 將動畫組對象添加到redView的layer上 ******************/
[_animationGroupView.layer addAnimation:groupAnim forKey:nil];
轉場動畫(CATranstion)
CATransition是CAAnimation的子類,用于做轉場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。iOS比Mac OS X的轉場動畫效果少一點
UINavigationController就是通過CATransition實現了將控制器的視圖推入屏幕的動畫效果
動畫屬性:
type:動畫過渡類型
subtype:動畫過渡方向
startProgress:動畫起點(在整體動畫的百分比)
endProgress:動畫終點(在整體動畫的百分比)