iOS的動(dòng)畫效果一直都很棒很,給人的感覺就是很炫酷很流暢,起到增強(qiáng)用戶體驗(yàn)的作用。在APP開發(fā)中實(shí)現(xiàn)動(dòng)畫效果有很多種方式,對(duì)于簡(jiǎn)單的應(yīng)用場(chǎng)景,我們可以使用UIKit提供的動(dòng)畫來實(shí)現(xiàn)。
UIView動(dòng)畫簡(jiǎn)介
UIView動(dòng)畫實(shí)質(zhì)上是對(duì)Core Animation的封裝,提供簡(jiǎn)潔的動(dòng)畫接口。
UIView動(dòng)畫可以設(shè)置的動(dòng)畫屬性有:
1、大小變化(frame)
2、拉伸變化(bounds)
3、中心位置(center)
4、旋轉(zhuǎn)(transform)
5、透明度(alpha)
6、背景顏色(backgroundColor)
7、拉伸內(nèi)容(contentStretch)
UIview 類方法動(dòng)畫
1)動(dòng)畫的開始和結(jié)束方法
1.1 動(dòng)畫開始標(biāo)記
[UIView beginAnimations:(nullable NSString *) context:(nullable void *)];
第一個(gè)參數(shù):動(dòng)畫標(biāo)識(shí)
第二個(gè)參數(shù):附加參數(shù),在設(shè)置了代理的情況下,此參數(shù)將發(fā)送到setAnimationWillStartSelector和setAnimationDidStopSelector所指定的方法。大部分情況下,我們?cè)O(shè)置為nil即可。
1.2 結(jié)束動(dòng)畫標(biāo)記
[UIView commitAnimations];
2)動(dòng)畫參數(shù)的設(shè)置方法
//動(dòng)畫持續(xù)時(shí)間
[UIView setAnimationDuration:(NSTimeInterval)];
//動(dòng)畫的代理對(duì)象
[UIView setAnimationDelegate:(nullable id)];
//設(shè)置動(dòng)畫將開始時(shí)代理對(duì)象執(zhí)行的SEL
[UIView setAnimationWillStartSelector:(nullable SEL)];
//設(shè)置動(dòng)畫結(jié)束時(shí)代理對(duì)象執(zhí)行的SEL
[UIView setAnimationDidStopSelector:(nullable SEL)];
//設(shè)置動(dòng)畫延遲執(zhí)行的時(shí)間
[UIView setAnimationDelay:(NSTimeInterval)];
//設(shè)置動(dòng)畫的重復(fù)次數(shù)
[UIView setAnimationRepeatCount:(float)];
//設(shè)置動(dòng)畫的曲線
[UIView setAnimationCurve:(UIViewAnimationCurve)];
UIViewAnimationCurve的枚舉值如下:
UIViewAnimationCurveEaseInOut, // 慢進(jìn)慢出(默認(rèn)值)
UIViewAnimationCurveEaseIn, // 慢進(jìn)
UIViewAnimationCurveEaseOut, // 慢出
UIViewAnimationCurveLinear // 勻速
//設(shè)置是否從當(dāng)前狀態(tài)開始播放動(dòng)畫
[UIView setAnimationBeginsFromCurrentState:YES];
假設(shè)上一個(gè)動(dòng)畫正在播放,且尚未播放完畢,我們將要進(jìn)行一個(gè)新的動(dòng)畫:
當(dāng)為YES時(shí):動(dòng)畫將從上一個(gè)動(dòng)畫所在的狀態(tài)開始播放
當(dāng)為NO時(shí):動(dòng)畫將從上一個(gè)動(dòng)畫所指定的最終狀態(tài)開始播放(此時(shí)上一個(gè)動(dòng)畫馬上結(jié)束)
//設(shè)置動(dòng)畫是否繼續(xù)執(zhí)行相反的動(dòng)畫
[UIView setAnimationRepeatAutoreverses:(BOOL)];
//是否禁用動(dòng)畫效果(對(duì)象屬性依然會(huì)被改變,只是沒有動(dòng)畫效果)
[UIView setAnimationsEnabled:(BOOL)];
//設(shè)置視圖的過渡效果
[UIView setAnimationTransition:(UIViewAnimationTransition) forView:(nonnull UIView *) cache:(BOOL)];
第一個(gè)參數(shù):UIViewAnimationTransition的枚舉值如下
UIViewAnimationTransitionNone, //不使用動(dòng)畫
UIViewAnimationTransitionFlipFromLeft, //從左向右旋轉(zhuǎn)翻頁(yè)
UIViewAnimationTransitionFlipFromRight, //從右向左旋轉(zhuǎn)翻頁(yè)
UIViewAnimationTransitionCurlUp, //從下往上卷曲翻頁(yè)
UIViewAnimationTransitionCurlDown, //從上往下卷曲翻頁(yè)
第二個(gè)參數(shù):需要過渡效果的View
第三個(gè)參數(shù):是否使用視圖緩存,YES:視圖在開始和結(jié)束時(shí)渲染一次;NO:視圖在每一幀都渲染
3)實(shí)例代碼:
1、屬性變化動(dòng)畫(以frame變化為例)
- (void)changeFrame {
[UIView beginAnimations:@"FrameAni" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:@selector(startAni:)];
[UIView setAnimationDidStopSelector:@selector(stopAni:)];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
self.cartCenter.frame = self.centerShow.frame;
[UIView commitAnimations];
}
- (void)startAni:(NSString *)aniID {
NSLog(@"%@ start",aniID);
}
- (void)stopAni:(NSString *)aniID {
NSLog(@"%@ stop",aniID);
}
動(dòng)畫效果:

2、轉(zhuǎn)場(chǎng)效果動(dòng)畫(以Flip效果為例)
- (void)flipAni {
[UIView beginAnimations:@"FlipAni" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:@selector(startAni:)];
[UIView setAnimationDidStopSelector:@selector(stopAni:)];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.centerShow cache:YES];
self.centerShow.image = [UIImage imageNamed:@"service"];
[UIView commitAnimations];
}
動(dòng)畫效果:

UIview Block動(dòng)畫
iOS4.0以后,增加了Block動(dòng)畫塊,提供更簡(jiǎn)潔的方式來實(shí)現(xiàn)動(dòng)畫。
1)Block動(dòng)畫方法
1、最簡(jiǎn)潔的Block動(dòng)畫:包含時(shí)間和動(dòng)畫
[UIView animateWithDuration:(NSTimeInterval) //動(dòng)畫持續(xù)時(shí)間
animations:^{
//執(zhí)行的動(dòng)畫
}];
2、帶有動(dòng)畫完成回調(diào)的Block動(dòng)畫
[UIView animateWithDuration:(NSTimeInterval) //動(dòng)畫持續(xù)時(shí)間
animations:^{
//執(zhí)行的動(dòng)畫
} completion:^(BOOL finished) {
//動(dòng)畫執(zhí)行完畢后的操作
}];
3、可設(shè)置延遲時(shí)間和過渡效果的Block動(dòng)畫
[UIView animateWithDuration:(NSTimeInterval) //動(dòng)畫持續(xù)時(shí)間
delay:(NSTimeInterval) //動(dòng)畫延遲執(zhí)行的時(shí)間
options:(UIViewAnimationOptions) //動(dòng)畫的過渡效果
animations:^{
//執(zhí)行的動(dòng)畫
} completion:^(BOOL finished) {
//動(dòng)畫執(zhí)行完畢后的操作
}];
UIViewAnimationOptions的枚舉值如下,可組合使用:
UIViewAnimationOptionLayoutSubviews //進(jìn)行動(dòng)畫時(shí)布局子控件
UIViewAnimationOptionAllowUserInteraction //進(jìn)行動(dòng)畫時(shí)允許用戶交互
UIViewAnimationOptionBeginFromCurrentState //從當(dāng)前狀態(tài)開始動(dòng)畫
UIViewAnimationOptionRepeat //無限重復(fù)執(zhí)行動(dòng)畫
UIViewAnimationOptionAutoreverse //執(zhí)行動(dòng)畫回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動(dòng)畫的執(zhí)行時(shí)間設(shè)置
UIViewAnimationOptionOverrideInheritedCurve //忽略嵌套動(dòng)畫的曲線設(shè)置
UIViewAnimationOptionAllowAnimatedContent //轉(zhuǎn)場(chǎng):進(jìn)行動(dòng)畫時(shí)重繪視圖
UIViewAnimationOptionShowHideTransitionViews //轉(zhuǎn)場(chǎng):移除(添加和移除圖層的)動(dòng)畫效果
UIViewAnimationOptionOverrideInheritedOptions //不繼承父動(dòng)畫設(shè)置
UIViewAnimationOptionCurveEaseInOut //時(shí)間曲線,慢進(jìn)慢出(默認(rèn)值)
UIViewAnimationOptionCurveEaseIn //時(shí)間曲線,慢進(jìn)
UIViewAnimationOptionCurveEaseOut //時(shí)間曲線,慢出
UIViewAnimationOptionCurveLinear //時(shí)間曲線,勻速
UIViewAnimationOptionTransitionNone //轉(zhuǎn)場(chǎng),不使用動(dòng)畫
UIViewAnimationOptionTransitionFlipFromLeft //轉(zhuǎn)場(chǎng),從左向右旋轉(zhuǎn)翻頁(yè)
UIViewAnimationOptionTransitionFlipFromRight //轉(zhuǎn)場(chǎng),從右向左旋轉(zhuǎn)翻頁(yè)
UIViewAnimationOptionTransitionCurlUp //轉(zhuǎn)場(chǎng),下往上卷曲翻頁(yè)
UIViewAnimationOptionTransitionCurlDown //轉(zhuǎn)場(chǎng),從上往下卷曲翻頁(yè)
UIViewAnimationOptionTransitionCrossDissolve //轉(zhuǎn)場(chǎng),交叉消失和出現(xiàn)
UIViewAnimationOptionTransitionFlipFromTop //轉(zhuǎn)場(chǎng),從上向下旋轉(zhuǎn)翻頁(yè)
UIViewAnimationOptionTransitionFlipFromBottom //轉(zhuǎn)場(chǎng),從下向上旋轉(zhuǎn)翻頁(yè)
4、Spring動(dòng)畫
iOS7.0后新增Spring動(dòng)畫(iOS系統(tǒng)動(dòng)畫大部分采用Spring Animation,適用于所有可被添加動(dòng)畫效果的屬性)
[UIView animateWithDuration:(NSTimeInterval)//動(dòng)畫持續(xù)時(shí)間
delay:(NSTimeInterval)//動(dòng)畫延遲執(zhí)行的時(shí)間
usingSpringWithDamping:(CGFloat)//震動(dòng)效果,范圍0~1,數(shù)值越小震動(dòng)效果越明顯
initialSpringVelocity:(CGFloat)//初始速度,數(shù)值越大初始速度越快
options:(UIViewAnimationOptions)//動(dòng)畫的過渡效果
animations:^{
//執(zhí)行的動(dòng)畫
}
completion:^(BOOL finished) {
//動(dòng)畫執(zhí)行完畢后的操作
}];
5、Keyframes動(dòng)畫
iOS7.0后新增關(guān)鍵幀動(dòng)畫,支持屬性關(guān)鍵幀,不支持路徑關(guān)鍵幀
[UIView animateKeyframesWithDuration:(NSTimeInterval)//動(dòng)畫持續(xù)時(shí)間
delay:(NSTimeInterval)//動(dòng)畫延遲執(zhí)行的時(shí)間
options:(UIViewKeyframeAnimationOptions)//動(dòng)畫的過渡效果
animations:^{
//執(zhí)行的關(guān)鍵幀動(dòng)畫
}
completion:^(BOOL finished) {
//動(dòng)畫執(zhí)行完畢后的操作
}];
UIViewKeyframeAnimationOptions的枚舉值如下,可組合使用:
UIViewAnimationOptionLayoutSubviews //進(jìn)行動(dòng)畫時(shí)布局子控件
UIViewAnimationOptionAllowUserInteraction //進(jìn)行動(dòng)畫時(shí)允許用戶交互
UIViewAnimationOptionBeginFromCurrentState //從當(dāng)前狀態(tài)開始動(dòng)畫
UIViewAnimationOptionRepeat //無限重復(fù)執(zhí)行動(dòng)畫
UIViewAnimationOptionAutoreverse //執(zhí)行動(dòng)畫回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動(dòng)畫的執(zhí)行時(shí)間設(shè)置
UIViewAnimationOptionOverrideInheritedOptions //不繼承父動(dòng)畫設(shè)置
UIViewKeyframeAnimationOptionCalculationModeLinear //運(yùn)算模式 :連續(xù)
UIViewKeyframeAnimationOptionCalculationModeDiscrete //運(yùn)算模式 :離散
UIViewKeyframeAnimationOptionCalculationModePaced //運(yùn)算模式 :均勻執(zhí)行
UIViewKeyframeAnimationOptionCalculationModeCubic //運(yùn)算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //運(yùn)算模式 :平滑均勻
各種運(yùn)算模式的直觀比較如下圖:

增加關(guān)鍵幀的方法:
[UIView addKeyframeWithRelativeStartTime:(double)//動(dòng)畫開始的時(shí)間(占總時(shí)間的比例)
relativeDuration:(double) //動(dòng)畫持續(xù)時(shí)間(占總時(shí)間的比例)
animations:^{
//執(zhí)行的動(dòng)畫
}];
6、轉(zhuǎn)場(chǎng)動(dòng)畫
6.1 從舊視圖轉(zhuǎn)到新視圖的動(dòng)畫效果
[UIView transitionFromView:(nonnull UIView *)
toView:(nonnull UIView *)
duration:(NSTimeInterval)
options:(UIViewAnimationOptions)
completion:^(BOOL finished) {
//動(dòng)畫執(zhí)行完畢后的操作
}];
在該動(dòng)畫過程中,fromView 會(huì)從父視圖中移除,并講 toView 添加到父視圖中,注意轉(zhuǎn)場(chǎng)動(dòng)畫的作用對(duì)象是父視圖(過渡效果體現(xiàn)在父視圖上)。
調(diào)用該方法相當(dāng)于執(zhí)行下面兩句代碼:
[fromView.superview addSubview:toView];
[fromView removeFromSuperview];
6.2 單個(gè)視圖的過渡效果
[UIView transitionWithView:(nonnull UIView *)
duration:(NSTimeInterval)
options:(UIViewAnimationOptions)
animations:^{
//執(zhí)行的動(dòng)畫
}
completion:^(BOOL finished) {
//動(dòng)畫執(zhí)行完畢后的操作
}];
2)實(shí)例代碼:
1、普通動(dòng)畫
下面三段代碼都實(shí)現(xiàn)了相同的視圖frame的變化,不同之處只在于其延遲時(shí)間、過渡效果和結(jié)束回調(diào)。
- (void)blockAni1 {
[UIView animateWithDuration:1.0 animations:^{
self.cartCenter.frame = self.centerShow.frame;
}];
}
- (void)blockAni2 {
[UIView animateWithDuration:1.0 animations:^{
self.cartCenter.frame = self.centerShow.frame;
} completion:^(BOOL finished) {
NSLog(@"動(dòng)畫結(jié)束");
}];
}
- (void)blockAni3 {
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.cartCenter.frame = self.centerShow.frame;
} completion:^(BOOL finished) {
NSLog(@"動(dòng)畫結(jié)束");
}];
}
動(dòng)畫效果:

2、Spring動(dòng)畫
- (void)blockAni4 {
[UIView animateWithDuration:1.0 delay:0.f usingSpringWithDamping:0.5 initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveLinear animations:^{
self.cartCenter.frame = self.centerShow.frame;
} completion:^(BOOL finished) {
NSLog(@"動(dòng)畫結(jié)束");
}];
}
動(dòng)畫效果:

3、Keyframes動(dòng)畫
這里以實(shí)現(xiàn)視圖背景顏色變化(紅-綠-藍(lán)-紫)的過程來演示關(guān)鍵幀動(dòng)畫。
- (void)blockAni5 {
self.centerShow.image = nil;
[UIView animateKeyframesWithDuration:9.0 delay:0.f options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
[UIView addKeyframeWithRelativeStartTime:0.f relativeDuration:1.0 / 4 animations:^{
self.centerShow.backgroundColor = [UIColor colorWithRed:0.9475 green:0.1921 blue:0.1746 alpha:1.0];
}];
[UIView addKeyframeWithRelativeStartTime:1.0 / 4 relativeDuration:1.0 / 4 animations:^{
self.centerShow.backgroundColor = [UIColor colorWithRed:0.1064 green:0.6052 blue:0.0334 alpha:1.0];
}];
[UIView addKeyframeWithRelativeStartTime:2.0 / 4 relativeDuration:1.0 / 4 animations:^{
self.centerShow.backgroundColor = [UIColor colorWithRed:0.1366 green:0.3017 blue:0.8411 alpha:1.0];
}];
[UIView addKeyframeWithRelativeStartTime:3.0 / 4 relativeDuration:1.0 / 4 animations:^{
self.centerShow.backgroundColor = [UIColor colorWithRed:0.619 green:0.037 blue:0.6719 alpha:1.0];
}];
} completion:^(BOOL finished) {
NSLog(@"動(dòng)畫結(jié)束");
}];
}
動(dòng)畫效果:

4、轉(zhuǎn)場(chǎng)動(dòng)畫
4.1 單個(gè)視圖的過渡效果
- (void)blockAni6 {
[UIView transitionWithView:self.centerShow duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
self.centerShow.image = [UIImage imageNamed:@"Service"];
} completion:^(BOOL finished) {
NSLog(@"動(dòng)畫結(jié)束");
}];
}
動(dòng)畫效果:

4.2 從舊視圖轉(zhuǎn)到新視圖的動(dòng)畫效果
- (void)blockAni7 {
UIImageView * newCenterShow = [[UIImageView alloc]initWithFrame:self.centerShow.frame];
newCenterShow.image = [UIImage imageNamed:@"Service"];
[UIView transitionFromView:self.centerShow toView:newCenterShow duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
NSLog(@"動(dòng)畫結(jié)束");
}];
}
動(dòng)畫效果:

Next
接下來將更新核心動(dòng)畫Core Animation