iOS中動畫分爲兩類,UIView動畫 和 CALayer動畫
UIView動畫可以給UIView的部分屬性添加動畫效果
支持動畫的屬性有:frame、center、bounds、alpha、transform、backgroundColor等;UIView動畫也支持翻轉或翻頁動畫效果:UIViewAnimationTransitionXXX;
UIView動畫和CALayer動畫比較:
- UIView動畫本質上也是CALayer動畫;
- 通過UIView動畫執行之後,UIView的相關屬性已經真實改變;而CALayer動畫默認在執行完畢後,會自動返回回去;並且執行完成後,即使設置動畫fillMode不變後,爲它設置的屬性也並不會改變;
下面來看一個UIView動畫實例
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view cache:YES];
[UIView commitAnimations]; // 提交執行動畫
在第一個方法中,第一個參數是指定該動畫的名稱,第二個參數在動畫開始/結束的時候,會把這個參數給傳過來;兩個參數都可爲空。
除此之外還有其它方法:
+ (void)setAnimationDelegate:(nullable id)delegate;
// 設置代理
+ (void)setAnimationWillStartSelector:(nullable SEL)selector;
// 單獨指定Start監聽
+ (void)setAnimationDidStopSelector:(nullable SEL)selector;
// 單獨指定Stop監聽
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;
// 設置漸變效果,默認是UIViewAnimationCurveEaseInOut
......
設置代理之後,實現UIViewController的以下兩個方法
-(void)animationWillStart:(NSString *)animationID context:(void *)context // 開始
-(void)animDidStoped:(id)sender finished:(NSNumber *)finished context:(void *)context // 結束
上面是使用[UIView animation___]的形式,實現UIView動畫還可以通過Block的方式。
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
UIView只是一個矩形區域,真正負責顯示渲染的是CALayer;
CALayer
iOS中的層類,是圖形界面的基礎,所有的界面元素都源自於它;
UIView中有一個readonly的屬性就是layer;CALayer同樣也有frame,bounds,backgroundColor等屬性;如果一個控件是另一個控件的子控件,那麼這個控件中的layer也是另外一個控件的子layer
可以通過UIView的layer屬性,給視圖添加陰影,邊框等效果;
shadowOffset // 陰影偏移量
shadowColor // 陰影顏色
shadowOpacity // 陰影透明度,默認爲0
borderWidth // 邊框寬度
borderColor // 邊框顏色
CALayer特有的兩個屬性
anchorPoint // 錨點,默認是在視圖的中心,值爲(0.5,0.5),左上角爲(1,1);
position // position是錨點基於父視圖原點的位置;
修改position,錨點不變,但frame會變化;
修改錨點,position不變,但frame會變化;
view.layer.borderWidth = 10;
view.layer.borderColor = [UIColor greenColor].CGColor;
view.layer.cornerRadius = 10; // 圓角
view.layer.masksToBounds = YES; // 超出主圖層的部分剪切掉;
view.clipsToBounds = YES;
view.layer.bounds = CGRectMake(0, 0, 100, 100);
view.layer.position = CGPointMake(100, 100);
// 設置的image不是展示在主圖層上的,而是展示在子圖層上的;
view.layer.contents = (id)[UIImage imageName:@"xxx"].CGImage;
view.layer.shadowColor; // 陰影顏色
view.layer.shadowOffset = CGSizeMake(-10 ,0); // 設置陰影偏移
view.layer.shadowOpacity; // 陰影透明度,1:完全不透明
CALayer動畫3種實現形式
view.layer.transform = CATransform3DMakeTranslation(0, 0, 100);
NSValue *v = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0,-100,0)];
[view.layer setValue:v forKeyPath:@"transform"];
[view.layer setValue:@(100) forKeyPath:@"transform.translation.x"];
自定義CALayer
1.重寫drawInContext方法,在此方法中給layer繪製圖形,注意CALayer中的drawInContext方法,不會自動調用,只能通過setNeedsDisplay方法調用;
-(void)drawInContext:(ContextRef)ctx
2.另一個使用CALayer渲染的方法
layer.delegate = self;
// 在self這個對象中重寫
drawLayer:(CALayer *)layer inContext:(ContextRef)ctx // 在該方法中進行渲染;
每個UIView內部都默認關聯一個CALayer,這個Layer稱爲RootLayer,所有的非rootLayer,也就是手動創建的CALayer,都存在隱式動畫,也就是當對這些非rootLayer的部分屬性進行修改時,默認會自動附帶動畫效果;在UIView的頭文件中,包含Animatable的屬性都支持隱式動畫;
<1>.關閉隱式動畫
[CATransaction begin];
[CATransaction setDisableActions:YES];
[layer.bounds = CGRectMake(0, 0, 100, 100); // 隱式動畫;
[CATransaction commit];
CAAnimation
CAAnimation類中封裝了iOS中所有的動畫效果,動畫是添加在Layer上的,(CoreAnimation是直接作用在CALayer上)是動畫的觸發核心,常見的有透明,飄浮,縮放;
CAAnimation類是抽象父類,它有三個子類:
CAPropertyAnimation
- CABasicAnimation
- CAKeyFrameAnimation
CAAnimationGroup
CATransition
其中CAPropertyAnimation又有兩個子類,用來給CALayer的部分屬性添加動畫;
1.CABasicAnimation
keyPath;
fromValue;
toValue;
byValue;
keyPath就是CALayer中可以做動畫的屬性,比如position,對於position屬性,它是一個結構體,這時候我們還可以繼續指定keyPath爲position.x;調用構造方法animationWithKeyPath:@”position.x”;與此同時,fromValue和toValue也要改爲對應的keyPath對應的類型;
Example
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"position"; // 設置需要發生動畫的屬性
anim.keyPath = @"bounds"; // toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
anim.keyPath = @"transform"; // toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(PI, 0, 0, 1)];
anim.keyPath = @"transform.translation.y"; // toValue = @(100);
anim.fromValue;
anim.toValue;
anim.removedOnCompletion = NO; // 設置動畫執行完畢後不刪除動畫;
anim.fillMode = kCAFillModeForwards; // 設置保存動畫的最新狀態;
[layer addAnimation:anim forKey:nils]; // 添加核心動畫到layer;
2.CAKeyFrameAnimation
關鍵幀動畫,某一屬性按照一串數值來執行動畫
anim.keyPath; // 同上
anim.values;
anim.keyTimes; // 用於設置每一幀動畫結束的時候佔用總時長百分比;
anim.repeatCount; // 重複次數;
anim.timimgFunction = [CAMediaTimingFunction functionWithName:...]; // 動畫速率
anim.path; // 幀動畫還可以指定一個路徑,讓layer沿指定路徑運動;路徑對象爲一個CGMutablePathRef對象實例(路徑指定後需要手動release該路徑);
delegate;
// 動畫代理,指定爲一個NSObject對象,NSObject對象中有兩個方法animationDidStart 和animationDidStop,分別表示動畫開始和動畫結束;
[layer removeAnimationForKey:(NSString *)]; // 停止動畫
Example
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSArray *arr = [NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(100, 100)],
[NSValue valueWithCGPoint:CGPointMake(20, 20)],
[NSValue valueWithCGPoint:CGPointMake(200, 150)],
[NSValue valueWithCGPoint:CGPointMake(140, 210)],
[NSValue valueWithCGPoint:CGPointMake(200, 150)], nil];
anim.values = arr;
anim.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.1],
[NSNumber numberWithFloat:0.3],
[NSNumber numberWithFloat:0.4],
[NSNumber numberWithFloat:0.7],
[NSNumber numberWithFloat:1.0], nil];
anim.duration = 2;
[self.uiview.layer addAnimation:anim forKey:@""];
3.CATransition
主要用於提供一些過渡效果;
改變一個view的位置,角度等可以通過設置view.transform來實現;
CGAffineTransformMakeRotation
CGAffineTransformMakeScale
CGAffineTransformMakeTranslation
CGAffineTransformXXX:2D仿射變換,不屬於動畫,但是經常和動畫配合使用,view上的每個點按照一定規律變化,可做出縮放,旋轉,平移等效果;
[UIView beginAnimations:@"a" context:NULL];
[UIView setAnimationDuration:2];
self.uiview.transform = CGAffineTransformMakeScale(1.2, 1.7);
// self.uiview.transform = CGAffineTransformRotate(self.uiview.transform, M_PI / 4);
[UIView commitAnimations];
CATransition *anim = [CATransition animation];
anim.duration = 1.0;
anim.type = @"pageCurl"; // 動畫過渡類型 | cube | kCATransitionMoveIn
anim.subtype = kCATransitionFromRight; // 動畫過渡方向
anim.delegate =; // 代理
[view.layer addAnimation:aim forKey:nil];
UIView執行Transition(轉場)動畫
[UIView transitionWithView:view duration:2.0 options:UIViewAnimationOptionsTransitionFlipFromLeft animations:^{
view.image = [UIImage imageNamed:@""];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
} completion:^(BOOL finished){
}]; // 旋轉的同時切換圖片
3D動畫
view.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0); // 讓view繞y軸旋轉90度
4.CAAnimationGroup
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
anim.fromValue = (id)[UIColor redColor].CGColor;
anim.toValue = (id)[UIColor blueColor].CGColor;
anim.duration = 2;
CABasicAnimation *anim1 = [CABasicAnimation animationWithKeyPath:@"position.x"];
anim1.fromValue = (id)[NSNumber numberWithInt:100];
anim1.toValue = (id)[NSNumber numberWithInt:200];
anim1.duration = 2;
CAAnimationGroup * group = [CAAnimationGroup animation];
NSArray *arr = [NSArray arrayWithObjects:anim ,anim1 , nil];
group.animations = arr;
group.duration = 3;
[self.uiview.layer addAnimation:group forKey:@""];
Transform:動畫需要回到原始狀態的時候使用該動畫;
[UIView animationWithDuration:duration animations:^{
} completion:^(BOOL finished){
}];
[UIView animationWithDuration:duration delay:delay options:(UIViewAnimationOptions) animations:^{
} completion:^(BOOL finished){
}];
// 其中options選項常用如下
UIViewAnimationOptionCurveEaseInOut(開始由慢到快,結束由快到慢)
UIViewAnimationOptionCurveEaseIn(由慢到快)
UIViewAnimationOptionCurveEaseOut(由快到慢)
UIViewAnimationOptionCurveEaseLinear(線性)
關閉動畫
[UIView setAnimationsEnabled:NO]; // 整個應用程序中的UIView動畫都會失效;