016-iOS 動畫機(jī)制

iOS 動畫大致有以下幾類

  • UIView
  • Transform 仿射變換
  • KeyFrame
  • CoreAnimation

UIView

UIView 是最基礎(chǔ)的動畫,類似于 Android 中的屬性動畫,可以對 view 的視覺屬性進(jìn)行插值變換,比如旋轉(zhuǎn)、縮放、平移、顏色變換等。

UIView 支持的變換屬性大致分為三類

  • 坐標(biāo)尺寸
    • bounds
    • frame
    • center
  • 視圖顯示
    • backgroundColor
    • alpha
    • hidden
  • 形態(tài)變化
    • transform

一個動畫的基本實現(xiàn)有方法和 block 兩種。

方法實現(xiàn)

首先定義方法的屬性

    // 第一個參數(shù): 動畫標(biāo)識
    // 第二個參數(shù): 附加參數(shù),在設(shè)置代理情況下,此參數(shù)將發(fā)送到setAnimationWillStartSelector和setAnimationDidStopSelector所指定的方法,大部分情況,設(shè)置為nil.
    [UIView beginAnimations:@"myAnimation" context:nil];
    
    //動畫持續(xù)時間
    [UIView setAnimationDuration:2.0];
    
    //動畫的代理對象
    [UIView setAnimationDelegate:nil];
    
    //設(shè)置動畫開始前和結(jié)束后調(diào)用的方法
    [UIView setAnimationWillStartSelector:nil];
    [UIView setAnimationDidStopSelector:nil];
    
    //設(shè)置動畫重復(fù)次數(shù),HUGE_VALF 會無限重復(fù)
    [UIView setAnimationRepeatCount:HUGE_VALF];
    
    //設(shè)置是否從當(dāng)前狀態(tài)開始播放動畫
    /*假設(shè)上一個動畫正在播放,且尚未播放完畢,我們將要進(jìn)行一個新的動畫:
     當(dāng)為YES時:動畫將從上一個動畫所在的狀態(tài)開始播放
     當(dāng)為NO時:動畫將從上一個動畫所指定的最終狀態(tài)開始播放(此時上一個動畫馬上結(jié)束)*/
    [UIView setAnimationBeginsFromCurrentState:YES];
    
    //設(shè)置動畫插值器屬性
    //UIViewAnimationCurveEaseInOut,         // slow at beginning and end
    //UIViewAnimationCurveEaseIn,            // slow at beginning
    //UIViewAnimationCurveEaseOut,           // slow at end
    //UIViewAnimationCurveLinear,
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    
    //設(shè)置動畫是否反方向進(jìn)行
    [UIView setAnimationRepeatAutoreverses:YES];
    
    /* 動畫內(nèi)容 */
    
    // 結(jié)束動畫
    [UIView commitAnimations];

block 實現(xiàn)

iOS4 以后增加的 block 動畫,使用更簡潔的語法實現(xiàn)動畫效果。

[UIView animateWithDuration:(NSTimeInterval)  //動畫持續(xù)時間
              animations:^{
              //執(zhí)行的動畫
}];

[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat |UIViewAnimationOptionAutoreverse animations:^{
//動畫效果
    } completion:^(BOOL finished) {
    //完成后的操作
    }];

UIViewAnimationOptions的枚舉值有

 UIViewAnimationOptionLayoutSubviews            //進(jìn)行動畫時布局子控件
 UIViewAnimationOptionAllowUserInteraction      //進(jìn)行動畫時允許用戶交互
 UIViewAnimationOptionBeginFromCurrentState     //從當(dāng)前狀態(tài)開始動畫
 UIViewAnimationOptionRepeat                    //無限重復(fù)執(zhí)行動畫
 UIViewAnimationOptionAutoreverse               //執(zhí)行動畫回路
 UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫的執(zhí)行時間設(shè)置
 UIViewAnimationOptionOverrideInheritedCurve    //忽略嵌套動畫的曲線設(shè)置
 UIViewAnimationOptionAllowAnimatedContent      //轉(zhuǎn)場:進(jìn)行動畫時重繪視圖
 UIViewAnimationOptionShowHideTransitionViews   //轉(zhuǎn)場:移除(添加和移除圖層的)動畫效果
 UIViewAnimationOptionOverrideInheritedOptions  //不繼承父動畫設(shè)置

 UIViewAnimationOptionCurveEaseInOut            //時間曲線,慢進(jìn)慢出(默認(rèn)值)
 UIViewAnimationOptionCurveEaseIn               //時間曲線,慢進(jìn)
 UIViewAnimationOptionCurveEaseOut              //時間曲線,慢出
 UIViewAnimationOptionCurveLinear               //時間曲線,勻速

 UIViewAnimationOptionTransitionNone            //轉(zhuǎn)場,不使用動畫
 UIViewAnimationOptionTransitionFlipFromLeft    //轉(zhuǎn)場,從左向右旋轉(zhuǎn)翻頁
 UIViewAnimationOptionTransitionFlipFromRight   //轉(zhuǎn)場,從右向左旋轉(zhuǎn)翻頁
 UIViewAnimationOptionTransitionCurlUp          //轉(zhuǎn)場,下往上卷曲翻頁
 UIViewAnimationOptionTransitionCurlDown        //轉(zhuǎn)場,從上往下卷曲翻頁
 UIViewAnimationOptionTransitionCrossDissolve   //轉(zhuǎn)場,交叉消失和出現(xiàn)
 UIViewAnimationOptionTransitionFlipFromTop     //轉(zhuǎn)場,從上向下旋轉(zhuǎn)翻頁
 UIViewAnimationOptionTransitionFlipFromBottom  //轉(zhuǎn)場,從下向上旋轉(zhuǎn)翻頁

Spring 效果

ios7.0 以后新增了 Spring 動畫,可以實現(xiàn)類似彈簧的效果。

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

使用如下

    [UIView animateWithDuration: 2 delay: 0 usingSpringWithDamping: 0.6 initialSpringVelocity: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
        self.label1.center = self.view.center;
    } completion: nil];

Tips

  • bounds 和 frame 都能實現(xiàn)平移動畫,但是不能實現(xiàn)縮放動畫,bounds 和 frame 的平移坐標(biāo)系也不一樣,frame 是相對父 view 的坐標(biāo)系,而 bounds 是 view 自身的坐標(biāo)系,一般要實現(xiàn)的動畫應(yīng)該是用 frame 實現(xiàn)。
  • UILabel 設(shè)置 backgroundColor 是沒有動畫效果的,必須對 label 的 layer 設(shè)置 backgroundColor 才可以。
  • 如果在 block 選項中設(shè)置動畫無限重復(fù),則 completion 代碼塊永遠(yuǎn)不會執(zhí)行。

Transform 動畫

CoreGraphics 框架中的 CGAffineTransform 主要是用于處理形變變換,例如平移、縮放、旋轉(zhuǎn)等,采用二維坐標(biāo)系,在屏幕上向右為 X 軸正方向,向下為 Y 軸正方向。

平移

基于初始位置的平移

CGAffineTransformMakeTranslation(CGFloat tx,
  CGFloat ty) 

基于指定位置的平移

CGAffineTransformTranslate(CGAffineTransform t,
  CGFloat tx, CGFloat ty) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)

縮放

基于初始位置的縮放

CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)

基于指定位置的平移

CGAffineTransformScale(CGAffineTransform t,
  CGFloat sx, CGFloat sy)

旋轉(zhuǎn)

基于初始位置的縮放

CGAffineTransformMakeRotation(CGFloat angle)

基于指定位置的縮放

CGAffineTransformRotate(CGAffineTransform t,
  CGFloat angle)

還原狀態(tài)

CGAffineTransformIdentity

合并轉(zhuǎn)換

CGAffineTransformConcat(CGAffineTransform t1,
  CGAffineTransform t2)

可以將兩種仿射變換合并為一個 transform,其本質(zhì)是對變換矩陣的計算。

KeyFrame 動畫

關(guān)鍵幀動畫的主要思路是將動畫過程拆分為幾個小過程,也稱為關(guān)鍵幀,以相對時間點、相對時間段作為參考傳入關(guān)鍵幀,設(shè)置好插值系數(shù),就可以便捷的將多個小變換按順序執(zhí)行。

創(chuàng)建一個關(guān)鍵幀動畫

[UIView animateKeyframesWithDuration:10 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{}

傳入?yún)?shù)包括動畫持續(xù)時間,延遲,動畫插值系數(shù)選項和動畫,這里選項主要有

UIViewKeyframeAnimationOptionCalculationModeLinear      // 連續(xù)運算模式,線性
UIViewKeyframeAnimationOptionCalculationModeDiscrete    // 離散運算模式,只顯示關(guān)鍵幀
UIViewKeyframeAnimationOptionCalculationModePaced       // 均勻執(zhí)行運算模式,線性
UIViewKeyframeAnimationOptionCalculationModeCubic       // 平滑運算模式
UIViewKeyframeAnimationOptionCalculationModeCubicPaced  // 平滑均勻運算模式

接下來在 animations 代碼塊中加入動畫關(guān)鍵幀

[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.2 animations:^{
            self.label1.center = CGPointMake(200, 30);
        }];

這里傳入的第一個參數(shù)是關(guān)鍵幀開始的相對時間點,第二個參數(shù)是關(guān)鍵幀持續(xù)的相對時間段,最后一個就是具體的動畫了,所以時間點和時間段都是小于 1 的。

CoreAnimation

CoreAnimation 提供了一組在 iOS 和 MACOSX 上的通用動畫 API,大致可以分為以下幾類

  • CABasicAnimation 基本動畫
  • CATransition 轉(zhuǎn)場動畫
  • CAKeyframeAnimation 關(guān)鍵幀動畫
  • CAAnimationGrup 動畫組

首先要明確在 iOS 中任何 UIView 中都有一個內(nèi)部圖層 CALayer,UIView 會調(diào)用 drawRect 方法進(jìn)行圖層繪制,繪制結(jié)束將圖層拷貝到屏幕上,從而完成顯示。所以我們可以通過調(diào)整 Layer 上的屬性來實現(xiàn)動畫效果。當(dāng)然 CALayer 與 UIView 也有區(qū)別,UIView 可以響應(yīng)事件,而 CALayer 必須手動進(jìn)行事件響應(yīng)。

CAAnimation 是個抽象類,不能直接使用。CABaseAnimation 可以實現(xiàn)前面提到的大多數(shù)屬性動畫,它有以下幾個設(shè)置選項

  • duration 動畫持續(xù)時間
  • repeatCount 重復(fù)次數(shù),可以設(shè)置為 HUGE_VALF或者M(jìn)AXFLOAT
  • repeatDuration 重復(fù)時間
  • removedOnCompletion 默認(rèn)為 YES,代表動畫執(zhí)行完畢后就從圖層上移除,圖形會恢復(fù)到動畫執(zhí)行前的狀態(tài)。如果想讓圖層保持顯示動畫執(zhí)行后的狀態(tài),那就設(shè)置為 NO,不過還要設(shè)置 fillMode 為 kCAFillModeForwards
  • fillMode 決定當(dāng)前對象在非active時間段的行為。比如動畫開始之前或者動畫結(jié)束之
  • beginTime 可以用來設(shè)置動畫延遲執(zhí)行時間,若想延遲 2s,就設(shè)置為 CACurrentMediaTime()+2,CACurrentMediaTime() 為圖層的當(dāng)前時間
  • timingFunction 速度控制函數(shù),控制動畫運行的節(jié)奏
  • delegate 動畫代理

fillMode 支持以下選項

  • kCAFillModeRemoved 默認(rèn)值,動畫開始前和動畫結(jié)束后對 layer 都沒有影響,動畫結(jié)束后,layer 會恢復(fù)到之前的狀態(tài)
  • kCAFillModeForwards 當(dāng)動畫結(jié)束后,layer 會保持動畫最后的狀態(tài)
  • kCAFillModeBackwards 當(dāng)動畫加入了一個 layer 時就立即進(jìn)入初始狀態(tài)并等待動畫開始
  • kCAFillModeBoth 動畫加入后開始之前,layer 便處于動畫初始狀態(tài),動畫結(jié)束后 layer 保持動畫最后的狀態(tài)

timingFunction 支持以下幾種常見的

  • kCAMediaTimingFunctionLinear(線性) 勻速
  • kCAMediaTimingFunctionEaseIn(漸進(jìn)) 緩慢進(jìn)入,加速離開
  • kCAMediaTimingFunctionEaseOut(漸出) 全速進(jìn)入,減速到達(dá)
  • kCAMediaTimingFunctionEaseInEaseOut(漸進(jìn)漸出) 緩慢進(jìn)入,中間加速,減速到達(dá),默認(rèn)選項

CABaseAnimaition

使用 CABaseAnimation 基本思路就是設(shè)置好要調(diào)整的屬性、初始值、結(jié)束值、插值模式等,然后將動畫加入到相應(yīng)的層 layer 上去。

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(16, 16)];
    animation.toValue = [NSValue valueWithCGPoint:self.view.center];
    animation.duration = 1.0;
    animation.fillMode = kCAFillModeBoth;
    animation.removedOnCompletion = NO;//動畫結(jié)束后不回到原始狀態(tài)
    animation.autoreverses = YES;//允許反向動畫
    animation.repeatCount = HUGE_VALF;//無限循環(huán)
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [self.label1.layer addAnimation:animation forKey:@"myposition"];

在這里,keyPath 支持的屬性有

  • transform —— 3D變換,[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 0)],直接進(jìn)行3D變換
  • transform.scale —— 縮放,@(1.5),放大1.5倍
  • transform.scale.x —— 寬度縮放,@(1.5),寬放大1.5倍
  • transform.scale.y —— 高度縮放,@(1.5),高放大1.5倍
  • transform.rotation.x —— 圍繞x軸旋轉(zhuǎn),@(M_PI),x軸旋轉(zhuǎn)180度
  • transform.rotation.y —— 圍繞y軸旋轉(zhuǎn),@(M_PI),y軸旋轉(zhuǎn)180度
  • transform.rotation.z —— 圍繞z軸旋轉(zhuǎn),@(M_PI),z軸旋轉(zhuǎn)180度
  • position —— 位置(中心點的改變),[NSValue valueWithCGPoint:CGPointMake(100, 100)],中心點變?yōu)?100,100)
  • opacity —— 透明度,@(0.5),透明度變?yōu)?.5
  • bounds —— 大小的改變,中心點保持不變,[NSValue valueWithCGRect:CGRectMake(0, 0, 300, 300)],大小變?yōu)?300,300)
  • cornerRadius —— 圓角的設(shè)置 ,@(5),圓角設(shè)置為5
  • backgroundColor —— 背景顏色變換,(id)[UIColor redColor].CGColor,背景改為紅色
    contents,可以改變layer展示的圖片,(id)[UIImage imageNamed:@"12.png"].CGImage,將UIView的展示圖片改為12.png
  • strokeStart —— 從起始點開始變化,fromValue = 0,toValue = 1,為CAShapeLayer的屬性
  • strokeEnd —— 從結(jié)束的位置開始變化,fromValue = 1,toValue = 0.5,為CAShapeLayer的屬性
  • path —— 根據(jù)路徑來改變
  • rotaion.x —— 旋轉(zhuǎn),弧度,X軸
  • rotaion.y —— 旋轉(zhuǎn),弧度,Y軸
  • rotaion.z —— 旋轉(zhuǎn),弧度,Z軸
  • rotaion —— 旋轉(zhuǎn),弧度,Z軸,完全等同于rotation.z
  • ···

例如對于 background 屬性

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    animation.fromValue = (id)[UIColor cyanColor].CGColor;
    animation.toValue = (id)[UIColor magentaColor].CGColor;
    animation.duration = 1.0;
    animation.fillMode = kCAFillModeBoth;
    animation.removedOnCompletion = NO;//動畫結(jié)束后不回到原始狀態(tài)
    animation.autoreverses = YES;//允許反向動畫
    animation.repeatCount = HUGE_VALF;//無限循環(huán)
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [self.label1.layer addAnimation:animation forKey:@"bgcolor"];

CAKeyFrameAnimation

核心動畫也有關(guān)鍵幀動畫的 API,可以設(shè)置多個控制狀態(tài).

values 控制

  • 路徑移動
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *key1 = [NSValue valueWithCGPoint:CGPointMake(16, 16)];
    NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(150, 50)];
    NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(300, 250)];
    animation.values = @[key1, key2, key3, key4];
    animation.duration = 5;
    animation.delegate = nil;
    animation.autoreverses = YES;//是否執(zhí)行反方向動畫
    animation.repeatCount = HUGE_VALF;//重復(fù)執(zhí)行次數(shù)
    animation.removedOnCompletion = NO;//執(zhí)行后移除動畫
    animation.fillMode = kCAFillModeBoth;
    [self.label1.layer addAnimation:animation forKey:@"key_frame"];
  • 圖標(biāo)抖動
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    anim.values = @[@(-M_PI_4 * 0.2),@(M_PI_4 * 0.2), @(-M_PI_4 * 0.2)];
    anim.duration = 0;
    anim.repeatCount = CGFLOAT_MAX;
    [self.label1.layer addAnimation:anim forKey:@"key_frame"];
  • path 控制

設(shè)置了 animation 的 path 屬性后 values 屬性就會失效。

    CGFloat SCREEN_WIDTH = [UIScreen mainScreen].bounds.size.width;
    CGFloat SCREEN_HEIGHT = [UIScreen mainScreen].bounds.size.height;
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
    animation.path = path.CGPath;
    animation.duration = 2.0f;
    animation.autoreverses = YES;//是否執(zhí)行反方向動畫
    animation.repeatCount = HUGE_VALF;//重復(fù)執(zhí)行次數(shù)
    animation.removedOnCompletion = NO;//執(zhí)行后移除動畫
    animation.fillMode = kCAFillModeBoth;

    [self.label1.layer addAnimation:animation forKey:@"pathAnimation"];

CAAnimationGroup 組動畫

組動畫顧名思義就是將一組動畫放在一起并發(fā)執(zhí)行,主要用到 CAAnimationGroup 這個類。

    CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    positionAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(16, 16)];
    positionAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2)];
    
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    scaleAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1, 1)];
    scaleAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0.5, 1.5)];
    
    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.fromValue = @(-M_PI_4 * 0.2);
    rotationAnimation.toValue = @(M_PI_4 * 0.2);
    
    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    animationGroup.animations = @[positionAnimation, scaleAnimation, rotationAnimation];
    animationGroup.duration = 2;
    animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animationGroup.fillMode = kCAFillModeBoth;
    animationGroup.autoreverses = YES;
    animationGroup.repeatCount = HUGE_VALF;
    [self.label1.layer addAnimation:animationGroup forKey:@"AnimationGroup"];

用法大體與前面的類似,只要將所有生成的動畫都放在 CAAnimationGroup 的 animations 數(shù)組里就可以了。

CATransition 轉(zhuǎn)場動畫

也是 CAAnimation 的子類,主要用于做過渡動畫、轉(zhuǎn)場動畫等,重要的屬性有 type 和 subtype 兩種

type

表示過渡效果,公開 API 有四種

  • kCATransitionFade 漸變
  • kCATransitionMoveIn 進(jìn)入覆蓋
  • kCATransitionPush 推出
  • kCATransitionReveal 揭露離開

還有一些私有 API,不建議在上線開發(fā)中使用

subtype

表示過渡方向,有四種

  • kCATransitionFromRight 從右側(cè)進(jìn)入
  • kCATransitionFromLeft 從左側(cè)進(jìn)入
  • kCATransitionFromTop 從頂部進(jìn)入
  • kCATransitionFromBottom 從底部進(jìn)入

綜合使用的例子如下

    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromRight;
    transition.duration = 2.0;
    self.presentationView.image = [UIImage imageNamed:@"picture2"];
    [self.presentationView.layer addAnimation:transition forKey:@"myTrainsition"];

CATrainsition 還有兩個屬性用于控制動畫區(qū)間,startProgress 和 endProgress 分別表示在整體動畫中的起始點占比和結(jié)束點占比,設(shè)置了兩個屬性后會從整體的動畫段中截取相應(yīng)比例對應(yīng)的動畫進(jìn)行展示。

CALayer 繪制動畫

類似 Android 和 HTML5 中的畫布,iOS 中的圖層 CALayer 也可以進(jìn)行各種簡單的繪制,當(dāng)然直接復(fù)寫 UIView 的 drawRect 方法也可以實現(xiàn),但是實際上考慮到 CALayer 才是負(fù)責(zé)繪制的實體,基于內(nèi)聚功能、降低耦合的原則放在 CALayer 進(jìn)行繪制操作比較合適。

首先自定義一個 CALayer 繼承自 CALayer,然后對下面的方法進(jìn)行復(fù)寫

- (void)drawInContext:(CGContextRef)ctx

具體繪制的 API 這里不再贅述,網(wǎng)上有詳細(xì)的 API 可以查到,完成復(fù)寫后在自定義的 UIView 中進(jìn)行如下配置即可

    _customLayer = [YasicProgressLayer layer];
    _customLayer.frame = self.bounds;
    _customLayer.contentsScale = [UIScreen mainScreen].scale;
    [self.layer addSublayer:_customLayer];

要注意的是在使用 View 的時候繪制操作依賴于自定義 View 的 bounds 信息,所以要在 viewDidLayoutSubviews 方法中啟動重繪。

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

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

  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,696評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,270評論 5 13
  • Core Animation其實是一個令人誤解的命名。你可能認(rèn)為它只是用來做動畫的,但實際上它是從一個叫做Laye...
    小貓仔閱讀 3,968評論 1 4
  • 轉(zhuǎn)載:http://www.itdecent.cn/p/32fcadd12108 每個UIView有一個伙伴稱為l...
    F麥子閱讀 6,594評論 0 13
  • Core Animation Core Animation,中文翻譯為核心動畫,它是一組非常強(qiáng)大的動畫處理API,...
    45b645c5912e閱讀 3,158評論 0 21

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