核心動畫

CALayer

  • CALayer負責視圖中顯示內容和動畫

  • UIView負責監聽和響應事件。在創建UIView對象時,UIView內部會自動創建一個圖層(CALayer對象),通過UIView的layer屬性可以訪問這個層。

  • 當UIView需要顯示到屏幕上時,會調用drawRect:方法進行繪圖,并且會將所有內容繪制在自己的圖層上,繪圖完畢后,系統會將圖層拷貝到屏幕上,于是就完成UIView的顯示。

  • 每一個UIView內部都默認關聯著一個CALayer,我們可稱這個Layer為Root Layer(根層)。所有的非Root Layer,也就是手動創建的CALayer對象,都存在著隱式動畫

  • CALayer是定義在QuartzCore框架中的

  • CGImageRef、CGColorRef兩種數據類型是定義在CoreGraphics框架中的

  • UIColor、UIImage是定義在UIKit框架中的

  • QuartzCore框架和CoreGraphics框架是可以跨平臺使用的,在iOS和Mac OS X上都能使用(C 語言編寫)。但是UIKit只能在iOS中使用(Objective-C)

  • 為了保證可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef 導入其他框架的方式: 選中項目, 在 General中找 Linked Frameworks and Libraries添加對應的框架

什么是隱式動畫?

  • 當對非Root Layer的部分屬性進行修改時,默認會自動產生一些動畫效果 而這些屬性稱為Animatable Properties(可動畫屬性)

  • 列舉幾個常見的Animatable Properties:
    bounds:用于設置CALayer的寬度和高度。修改這個屬性會產生縮放動畫
    backgroundColor:用于設置CALayer的背景色。修改這個屬性會產生背景色的漸變動畫
    position:用于設置CALayer的位置。修改這個屬性會產生平移動畫

可通過動畫事務CATransaction關閉默認的隱式動畫效果

[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myView.layer.position = CGPointMake(10, 10);
[CATransaction commit];

UIView和CALayer的選擇

  • 通過CALayer,就能做出跟UIImageView一樣的界面效果
既然CALayer和UIView都能實現相同的顯示效果,那究竟該選擇誰好呢?

其實,對比CALayer,UIView多了一個事件處理的功能。也就是說,CALayer不能處理用戶的觸摸事件,而UIView可以。所以,如果顯示出來的東西需要跟用戶進行交互的話,用UIView;如果不需要跟用戶進行交互,用UIView或者CALayer都可以 當然,CALayer的性能會高一些,因為它少了事件處理的功能,更加輕量級

  • 注:UIView本身不具備顯示的功能,是它內部的層才有顯示功能。
- (void)viewDidLoad{
   [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

   UIView* redView = [[UIView alloc] init];

   redView.frame = CGRectMake(100, 100, 100, 100);

   redView.backgroundColor = [UIColor redColor];

   [self.view addSubview:redView];

   // 1>邊框
   redView.layer.borderWidth = 10; // 邊框的寬度

   redView.layer.borderColor = [UIColor whiteColor].CGColor; // 邊框的顏色

   // 2>陰影
   redView.layer.shadowOffset = CGSizeMake(50, 50); // 偏移量  

   redView.layer.shadowColor = [UIColor blueColor].CGColor; // 顏色

   redView.layer.shadowOpacity = 1; // 透明度 (如果要顯示 一定要加)

   redView.layer.shadowRadius = 50; // 陰影的圓角半徑

   // 3>圓角
   redView.layer.cornerRadius = 50;

   redView.layer.masksToBounds = YES;

  // 4>bounds

  redView.layer.bounds = CGRectMake(0, 0, 200, 200);

  // 5>postion屬性和view.center的關系 默認

  redView.layer.position = CGPointMake(100, 100);

  // 6>設置內容(圖片)

   redView.layer.contents = (__bridge id)([UIImage imageNamed:@"me"].CGImage);
}

CALayer的transform屬性

// 旋轉 
self.layer.transform = CATransform3DRotate(self.layer.transform, M_PI_4, 0, 0, 1); 

// 縮放  z軸無效果 
self.layer.transform = CATransform3DScale(self.layer.transform, 1, 1, 0.5); 
// 平移 z軸無效果 
self.layer.transform = CATransform3DTranslate(self.layer.transform, 0, 0, 10);

核心動畫

  • Core Animation:核心動畫,是一組非常強大的動畫處理API。
  • Core Animation的動畫執行過程是在后臺執行的,不會阻塞主線程。Core Animation是直接作用在CALayer上的,并非UIView。

使用步驟:
1、創建動畫對象
2、設置動畫屬性
3、把動畫對象添加到某個CALayer對象上
4、需要停止動畫:可以調用remove方法移除動畫

  • CAAnimation是所有動畫對象的父類,負責控制動畫的持續時間和速度,是個抽象類,不能直接使用,應該使用它具體的子類.
  • 屬性解析:(紅色代表來自CAMediaTiming協議的屬性)

duration:動畫的持續時間

repeatCount:動畫的重復次數

repeatDuration:動畫的重復時間

removedOnCompletion:默認為YES,代表動畫執行完畢后就從圖層上移除,圖形會恢復到動畫執行前的狀態。如果想讓圖層保持顯示動畫執行后的狀態,那就設置為NO,不過還要設置fillMode為kCAFillModeForwards

fillMode:決定當前對象在非active時間段的行為.比如動畫開始之前,動畫結束之后

beginTime:可以用來設置動畫延遲執行時間,若想延遲2s,就設置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當前時間。

timingFunction:速度控制函數,控制動畫運行的節奏

基礎動畫(CABasicAnimation)

CAPropertyAnimation的子類

  • 屬性解析:
    fromValue:keyPath相應屬性的初始值
    toValue:keyPath相應屬性的結束值

  • 隨著動畫的進行,在長度為duration的持續時間內,keyPath相應屬性的值從fromValue漸漸地變為toValue

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) CALayer* layer;

@end

@implementation ViewController

- (void)viewDidLoad{ 

    [super viewDidLoad]; 

   // Do any additional setup after loading the view, typically from a nib. 

     UIView* redView = [[UIView alloc] init];

     redView.backgroundColor = [UIColor redColor]; 

     redView.frame = CGRectMake(100, 100, 100, 100); 

     [self.view addSubview:redView]; 

     self.layer = redView.layer;
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{ 

      // *1.基本動畫 

      // 1.創建動畫對象
      CABasicAnimation* anim = [[CABasicAnimation alloc] init]; 
 
      // 2.操作 
      anim.keyPath = @"position.x"; 

      // anim.fromValue = @(10); // 從哪 

      // anim.toValue = @(300); // 到哪 

      anim.byValue = @(10); // 在自身的基礎上累加 

      // 不希望核心動畫回到原來的位置 

      anim.fillMode = kCAFillModeForwards; 
    
      anim.removedOnCompletion = NO; 

     // 3.添加動畫
     [self.layer addAnimation:anim forKey:nil];
}
@end

關鍵幀動畫(CAKeyframeAnimation)

  • CApropertyAnimation的子類
    跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值

  • 屬性解析:

    values:就是上述的NSArray對象。里面的元素稱為”關鍵幀”(keyframe)。 動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀

    path:可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那么values將被忽略

    keyTimes:可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的

    CABasicAnimation可看做是最多只有2個關鍵幀的CAKeyframeAnimation

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) CALayer* layer;

@end

@implementation ViewController

- (void)viewDidLoad{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    UIView* redView = [[UIView alloc] init]; 

    redView.backgroundColor = [UIColor redColor]; 

    redView.frame = CGRectMake(100, 100, 20, 20); 
   
    [self.view addSubview:redView]; 

    self.layer = redView.layer;
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{ 

    // 1.創建動畫對象 
    CAKeyframeAnimation* anim = [[CAKeyframeAnimation alloc] init]; 

    // 2.操作
    anim.keyPath = @"position"; 

    // 創建一個圓的路徑 
    UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 160, 160)]; anim.path = path.CGPath; 

    // 設置時間
     anim.duration = 3; 

    // 設置重復次數 
    anim.repeatCount = INT_MAX; 

    // 3.添加動畫 
    [self.layer addAnimation:anim forKey:nil];
}

轉場動畫(CATransition)

  • CAAnimation的子類,用于做轉場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。
  • UINavigationController就是通過CATransition實現了將控制器的視圖推入屏幕的動畫效果
  • 屬性解析:
    type:動畫過渡類型
    subtype:動畫過渡方向
    startProgress:動畫起點(在整體動畫的百分比)
    endProgress:動畫終點(在整體動畫的百分比)
#import "ViewController.h"

@interface ViewController()<UIGestureRecognizerDelegate>

@property (nonatomic, strong) UIImageView* imageView;

@property (nonatomic, assign) int index;

@end

@implementation ViewController

//懶加載創建并添加imageView到view上

-(UIImageView *)imageView{

   if (_imageView == nil) { 

      // 獲取圖片 
      NSString* imageName = [NSString stringWithFormat:@"%d", self.index]; 

      UIImage* image = [UIImage imageNamed:imageName]; 

      //創建視圖控制器 
      _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, 300, 400)]; 

      _imageView.image = image; //打開交互 
  
      _imageView.userInteractionEnabled = YES; 

      [self.view addSubview:_imageView]; 

  } 

 return _imageView;
}

- (void)viewDidLoad { 
   [super viewDidLoad]; 

   self.index = 1;

   [self addSwipe];

}

- (void)addSwipe{ 
   //添加輕掃手勢
   UISwipeGestureRecognizer* swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; 

   UISwipeGestureRecognizer* swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; 

   swipeRight.direction = UISwipeGestureRecognizerDirectionLeft; 
   
   [self.imageView addGestureRecognizer:swipeLeft]; 

   [self.imageView addGestureRecognizer:swipeRight];
}
- (void)swipe:(UISwipeGestureRecognizer*)sender{ 

    // 轉場動畫 
    // 1.創建動畫 
    CATransition* anim = [[CATransition alloc] init]; 

    // 2.操作 
    anim.type = @"cameraIrisHollowOpen"; 

    if (sender.direction == UISwipeGestureRecognizerDirectionLeft) { 
    
        anim.subtype = kCATransitionFromLeft;

        self.index ++; 
     }else { 

        anim.subtype = kCATransitionFromRight; 

        self.index --; 
     } 

    if (self.index == 6) { 
 
       self.index = 1;
     } 

    if (self.index == 0) { 

       self.index = 5; 
     } 
  
   self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d",self.index]]; 

   [self.imageView.layer addAnimation:anim forKey:nil];
}
@end

組動畫(CAAnimationGroup)

  • CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層后,組中所有動畫對象可以同時并發運行

  • 屬性解析:
    animations:用來保存一組動畫對象的NSArray

默認情況下,一組動畫對象是同時運行的,也可以通過設置動畫對象的beginTime屬性來更改動畫的開始時間。

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) CALayer* layer;

@end

@implementation ViewController

- (void)viewDidLoad{ 

   [super viewDidLoad]; 
   // Do any additional setup after loading the view, typically from a nib. 

   UIView* redView = [[UIView alloc] init]; 

   redView.backgroundColor = [UIColor redColor]; 

   redView.frame = CGRectMake(100, 100, 20, 20); 

   [self.view addSubview:redView]; 

   self.layer = redView.layer;
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{ 

    // 組動畫 
    // 1.創建動畫對象
    CAAnimationGroup* group = [[CAAnimationGroup alloc] init]; 

    // 2.操作 
    // *1.關鍵幀動畫 - 繞著圓的路徑轉 
    // ------ 
    // 1.創建動畫對象 
    CAKeyframeAnimation* anim = [[CAKeyframeAnimation alloc] init]; 

    // 2.操作
    anim.keyPath = @"position"; 

    // 創建一個圓的路徑 
    UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:80 startAngle:0 endAngle:2 * M_PI clockwise:1]; 

    anim.path = path.CGPath; 
    // ------ 
    // *2.基本動畫 - 自轉 
    // ------ 
    // 1.創建動畫 
    CABasicAnimation* anim1 = [[CABasicAnimation alloc] init]; 

    // 2.操作 
    anim1.keyPath = @"transform.rotation"; anim1.byValue = @(M_PI * 2 * 3); 

    // ------ 
    group.animations = @[ anim, anim1 ];

    // 設置事件 
    group.duration = 3; 

    // 設置次數 
    group.repeatCount = INT_MAX; 

    // 3.添加動畫 
    [self.layer addAnimation:group forKey:nil];
}
@end
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Core Animation Core Animation,中文翻譯為核心動畫,它是一組非常強大的動畫處理API,...
    45b645c5912e閱讀 3,052評論 0 21
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現這些動畫的過程并不復雜,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,557評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現這些動畫的過程并不復雜,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,141評論 5 13
  • 核心動畫(Core Animation)一、Core animation簡單介紹 1.Core Animatio...
    北辰青閱讀 1,088評論 0 1
  • CALayer - 在iOS中,你能看得見摸得著的東西基本上都是UIView,比如一個按鈕、一個文本標簽、一個文本...
    Hevin_Chen閱讀 1,146評論 0 10