iOS動(dòng)畫篇:UIView動(dòng)畫

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)畫效果:

NormalAni.gif

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)畫效果:

ScreenTransitionAni.gif

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)算模式的直觀比較如下圖:


圖片來源網(wǎng)絡(luò).png

增加關(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)畫效果:

NormalAni.gif

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)畫效果:

SpringAni.gif

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)畫效果:

KeyFramesAni.gif

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)畫效果:

TransitionAni.gif

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)畫效果:

ScreenTransitionAni.gif

Next

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在開發(fā)工作中,我們會(huì)碰到大量的需要表現(xiàn)力的地方,那么動(dòng)畫便成為了我們開發(fā)過程中必不可少的知識(shí)點(diǎn)。 那么,首先我們從...
    穿山甲救蛇精閱讀 2,631評(píng)論 2 15
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場(chǎng)動(dòng)畫。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,313評(píng)論 1 23
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,688評(píng)論 6 30
  • 概覽 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你...
    Yiart閱讀 3,960評(píng)論 3 34
  • 合理的分布章節(jié),每個(gè)章節(jié)獨(dú)立而又連接緊密。 給人設(shè)更多的選擇空間,精神才是人設(shè)的內(nèi)涵。 架構(gòu)上留下足夠豐富的二次創(chuàng)...
    等待三月腐草為螢閱讀 389評(píng)論 0 1

友情鏈接更多精彩內(nèi)容