iOS引入動畫效果可以使我們的軟件得到更好的用戶體驗,因此動畫的深入研究無疑對於開發者一個很好的加分項。
CALayer層的操作
UIView的操作
UIView裡面包含有一個CALayer層
UIView之所以能夠在屏幕上顯示出來,完全因為其內部擁有一個CALayer層
CALayer層的操作更底層更輕量級、性能更高。
UIView動畫執行完畢之後不會反彈,而CALayer動畫改變layer的狀態位置,出現假象的改變,其實實際位置並沒有改變
每個UIView的操作其實是對CALayer層的封裝,比較簡單,優先選擇UIView動畫操作。
操作CALayer層更直接,能實現UIView所不能實現的功能
[UIView beginAnimations:nil context:nil] ;
//需要執行動畫的核心代碼
//設置動畫執行時間
[UIView setAnimationDuration:2.0];
//設置代理
[UIView setAnimationDelegate:self];
//設置動畫執行完畢調用的事件
[UIView setAnimationDidStopSelector:@selector(didStopAnimation)];
self.customView.center=CGPointMake(200, 300);
[UIView commitAnimations];
+ (void)setAnimationDelegate:(id)delegate 設置動畫代理對象,當動畫開始或者結束時會發消息給代理對象
+ (void)setAnimationWillStartSelector:(SEL)selector 當動畫即將開始時,執行delegate對象的selector,並且把beginAnimations:context:中傳入的參數傳進selector
+ (void)setAnimationDidStopSelector:(SEL)selector 當動畫結束時,執行delegate對象的selector,並且把beginAnimations:context:中傳入的參數傳進selector
+ (void)setAnimationDuration:(NSTimeInterval)duration 動畫的持續時間,秒為單位
+ (void)setAnimationDelay:(NSTimeInterval)delay 動畫延遲delay秒後再開始
+ (void)setAnimationStartDate:(NSDate *)startDate 動畫的開始時間,默認為now
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve 動畫的節奏控制
+ (void)setAnimationRepeatCount:(float)repeatCount 動畫的重復次數
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses 如果設置為YES,代表動畫每次重復執行的效果會跟上一次相反
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache 設置視圖view的過渡效果, transition指定過渡類型, cache設置YES代表使用視圖緩存,性能較好
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
duration:動畫的持續時間
delay:動畫延遲delay秒後開始
options:動畫的節奏控制
animations:將改變視圖屬性的代碼放在這個block中
completion:動畫結束後,會自動調用這個block
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
duration:動畫的持續時間
view:需要進行轉場動畫的視圖
options:轉場動畫的類型
animations:將改變視圖屬性的代碼放在這個block中
completion:動畫結束後,會自動調用這個block
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
duration:動畫的持續時間
options:轉場動畫的類型
animations:將改變視圖屬性的代碼放在這個block中
completion:動畫結束後,會自動調用這個block
options參數的詳細的枚舉
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
UIViewAnimationOptionLayoutSubviews = 1 << 0,
UIViewAnimationOptionAllowUserInteraction = 1 << 1, // turn on user interaction while animating
UIViewAnimationOptionBeginFromCurrentState = 1 << 2, // start all views from current value, not initial value
UIViewAnimationOptionRepeat = 1 << 3, // repeat animation indefinitely
UIViewAnimationOptionAutoreverse = 1 << 4, // if repeat, run animation back and forth
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5, // ignore nested duration
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6, // ignore nested curve
UIViewAnimationOptionAllowAnimatedContent = 1 << 7, // animate contents (applies to transitions only)
UIViewAnimationOptionShowHideTransitionViews = 1 << 8, // flip to/from hidden state instead of adding/removing
UIViewAnimationOptionOverrideInheritedOptions = 1 << 9, // do not inherit any options or animation type
UIViewAnimationOptionCurveEaseInOut = 0 << 16, // default
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
UIViewAnimationOptionTransitionNone = 0 << 20, // default
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
UIViewAnimationOptionTransitionCurlUp = 3 << 20,
UIViewAnimationOptionTransitionCurlDown = 4 << 20,
UIViewAnimationOptionTransitionCrossDissolve = 5 << 20,
UIViewAnimationOptionTransitionFlipFromTop = 6 << 20,
UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20,
} NS_ENUM_AVAILABLE_IOS(4_0);
position位置(原點為父類的(0,0))
anchorPoint 錨點(默認原點在自身長和寬各一半的交點(0.5,0.5))
簡單說,每個控件都有一個自帶的CALayer層,這個層稱為根層,與之相對於的就是非根層,非根層的的屬性改變就會默認引發動畫,這樣的動畫就可以稱為隱式動畫
[CATransaction begin];
[CATransaction setDisableActions:YES];
//......這裡修改你想修改的Layer屬性就不會產生默認的隱式動畫
[CATransaction commit];
CAAnimation是所有動畫類的父類,它和CAPropertyAnimation不能直接使用,應該使用它的子類CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup
fromValue:keyPath相應屬性值的初始值
toValue:keyPath相應屬性的結束值
byValue : 增加多少值(注意對比toValue的意思)
keyPath內容是CALayer的可動畫Animation屬性
// 1.創建動畫對象
CABasicAnimation *anim = [CABasicAnimation animation];
// 2.設置動畫對象
// keyPath決定了執行怎樣的動畫, 調整哪個屬性來執行動畫
anim.keyPath = @"transform.translation.x";
anim.toValue = @(100);
//執行的時間
anim.duration = 2.0;
//加入下面兩行,當動畫結束時,layer所在的位置不會回到初始位置
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
// 3.添加動畫
[self.layer addAnimation:anim forKey:nil];
CAKeyframeAnimation是CABasicAnimation的升級版,CABasicAnimation只能改變一組屬性動畫就停止了,而CAKeyframeAnimation可以運行關於一個屬性的一個數組的數據(這裡需要特別注意是同一個屬性的一組數據)
values:所有的值
path:路線
keyTimes:可以為對應的關鍵幀制定對應的時間點,取值范圍是0到1.0
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
anim.keyPath = @"transform.rotation";
anim.values = array;
anim.duration = 0.25;
// 動畫的重復執行次數
anim.repeatCount = MAXFLOAT;
// 保持動畫執行完畢後的狀態
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
[self.redView.layer addAnimation:anim forKey:nil];
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
anim.keyPath = @"position";
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
anim.duration = 2.0;
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(100, 100, 200, 200));
anim.path = path;
CGPathRelease(path);
// 設置動畫的執行節奏
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.delegate = self;
[self.redView.layer addAnimation:anim forKey:nil];
我們上面兩個動畫類都是只能對同一個屬性進行修改產生動畫,而不能同時修改兩個參數屬性。所有就引入了CAAnimationGroup動畫組
最經典的莫過於:邊旋轉邊縮放邊移動的動畫效果,其實就是前面的基礎動畫加入到動畫組形成的
// 1.創建旋轉動畫對象
CABasicAnimation *rotate = [CABasicAnimation animation];
rotate.keyPath = @"transform.rotation";
rotate.toValue = @(M_PI);
// 2.創建縮放動畫對象
CABasicAnimation *scale = [CABasicAnimation animation];
scale.keyPath = @"transform.scale";
scale.toValue = @(0.0);
// 3.平移動畫
CABasicAnimation *move = [CABasicAnimation animation];
move.keyPath = @"transform.translation";
move.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
// 4.將所有的動畫添加到動畫組中
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[rotate, scale, move];
group.duration = 2.0;
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
[self.myvie.layer addAnimation:group forKey:nil];
提供移除屏幕和移入屏幕的動畫效果
/** 轉場動畫代碼 */
// 創建轉場動畫對象
CATransition *anim = [CATransition animation];
// 設置轉場類型
anim.type = @"pageCurl";
// 設置動畫的方向
anim.subtype = kCATransitionFromLeft;
anim.duration = 3;
[_imageV.layer addAnimation:anim forKey:nil];
type:動畫過渡類型 subtype:動畫過渡方向
+(void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:
(UIViewAnimationOptions)options
animations:(void(^)(void))animations
completion:(void(^)(BOOLfinished))completion;
duration:動畫的持續時間 view:需要進行轉場動畫的視圖 options:轉場動畫的類型 animations:將改變視圖屬性的代碼放在這個block中 completion:動畫結束後,會自動調用這個block
+ (void)transitionFromView:(UIView*) fromView
toView:(UIView*) toViewduration:(NSTimeInterval)durationoptions:(UIViewAnimationOptions) options
completion:(void(^)(BOOLfinished))completion;
duration:動畫的持續時間 options:轉場動畫的類型 animations:將改變視圖屬性的代碼放在這個block中 completion:動畫結束後,會自動調用這個block
動畫也是存在代理的,實現代理可以在動畫開始的時候調用和動畫結束的時候調用的時候做些事情
anim.delegate = self;
#pragma mark 動畫開始的時候調用
- (void)animationDidStart:(CAAnimation *)anim
{
}
#pragma mark 動畫結束的時候調用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
}