天天看點

Core Animation 學習筆記(二)

Core Animation 學習筆記(二)

1.專用圖層(Specialized Layers)

常用的圖層大概有下面這幾個:

CAShapeLayer

CATextLayer

CATransformLayer

CAGradientLayer

CAReplicatorLayer

CAScrollLayer

CATiledLayer

CAEmitterLayer

CAEAGLLayer

AVPlayerLayer

目前我隻用過其中的幾個,就簡單講講自己用過的吧!

(1)CAShapeLayer是一個通過矢量圖形而不是bitmap來繪制的圖層子類。你指定諸如顔色和線寬等屬性,用CGPath來定義想要繪制的圖形,最後CAShapeLayer就會自動渲染出來。通常使用CAShapeLayer結合UIBezierPath繪制簡單圖形。用CAShapeLayer可以為每個角指定是否圓角。

下面這段代碼繪制了一個有三個圓角一個直角的矩形:

// 定義路徑參數

CGRect rect = CGRectMake(50, 50, 100, 100);

CGSize radii = CGSizeMake(20, 20);

UIRectCorner corners = UIRectCornerTopRight | UIRectCornerBottomRight | UIRectCornerBottomLeft;

// 建立路徑

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];

(2)CAGradientLayer是用來生成兩種或更多顔色平滑漸變的。用Core Graphics複制一個CAGradientLayer并将内容繪制到一個普通圖層的寄宿圖也可以實作這個效果,但是CAGradientLayer的真正好處在于繪制使用了硬體加速。使用CAGradientLayer不僅可以實作基礎漸變(一種顔色漸變到另一種顔色),還能實作多重漸變(一種顔色漸變到多種顔色)。下面是一段多種漸變的例子:

- (void)viewDidLoad {

    [super viewDidLoad];

    // 建立梯度圖層并添加到容器視圖上

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];

    gradientLayer.frame = self.containerView.bounds;

    [self.containerView.layer addSublayer:gradientLayer];

    // 設定梯度顔色

    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id [UIColor yellowColor].CGColor, (__bridge id)[UIColor greenColor].CGColor];

    // 設定位置

    gradientLayer.locations = @[@0.0, @0.25, @0.5];

    // 設定梯度開始和結束點

    gradientLayer.startPoint = CGPointMake(0, 0);

    gradientLayer.endPoint = CGPointMake(1, 1); 

}

Core Animation 學習筆記(二)

(3)CAReplicatorLayer可以高效生成許多相似的圖層。它會繪制一個或多個圖層的子圖層,并在每個 複制體上應用不同的變換。變換是逐漸增加的,每個執行個體都是相 對于前一執行個體布局。這就是為什麼這些複制體最終不會出現在同意位置上.使用CAReplicatorLayer和CAGradientLayer可以實作倒影的效果。

Core Animation 學習筆記(二)

2.隐式動畫(Implicit Animations)

當改變CALayer那個是否可以做動畫的屬性時,并不能立刻在螢幕上展現出來。相反,它是從先前的值平滑過渡到新的值。這一切都是預設的行為,你不需要做額外的操作。例如改變圖層顔色

self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;

這其實就是所謂的隐式動畫。之是以叫内聯是因為我們并沒有指定任何動畫的類型。改變了一個屬性,然後Core Animation來決定如何并且何時去做動畫。

(1)事務

事務指的是Core Animation用來包含一系列屬性動畫集合的機制,任何用指定事務去改變做動畫的圖層,屬性都不會立刻發生變化,而是當事務一旦送出的時候開始用一個動畫過渡到新值。使用CATransaction控制動畫時間

- (IBAction)changeColor

{

    // 開始一個新的事務

    [CATransaction begin];

    // 設定1秒的動畫

    [CATransaction setAnimationDuration:1.0];

    // 随機給背景配色

    CGFloat red = arc4random() / (CGFloat)INT_MAX;

    CGFloat green = arc4random() / (CGFloat)INT_MAX;

    CGFloat blue = arc4random() / (CGFloat)INT_MAX;

    self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;

 // 送出事務

    [CATransaction commit];

}

注意:UIView關聯的圖層禁用了隐式動畫,對這種圖層做動畫的唯一辦法就是使用UIView的動畫函數。

3.顯示動畫(Implicit Animations)

(1)屬性動畫

動畫其實就是一段時間内發生的改變,最簡單的形式就是從一個值改變到另一個值,這也是CABasicAnimation最主要的功能。

- (IBAction)changeColor

{

    // 建立一個新的随機顔色

    CGFloat red = arc4random() / (CGFloat)INT_MAX;

    CGFloat green = arc4random() / (CGFloat)INT_MAX;

    CGFloat blue = arc4random() / (CGFloat)INT_MAX;

    UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];

    // 建立一個基本動畫

    CABasicAnimation *animation = [CABasicAnimation animation];

    animation.keyPath = @"backgroundColor";

    animation.toValue = (__bridge id)color.CGColor;

    // 在圖層上設定動畫

    [self.colorLayer addAnimation:animation forKey:nil];

}

運作程式,結果有點差強人意,點選按鈕,的确可以使圖層動畫過渡到一個新的顔色,然動畫結束之後又立刻變回原始值。

這是因為動畫并沒有改變圖層的模型,而隻是展現。一旦動畫結束并從圖層上移除之後,圖層就立刻恢複到之前定義的外觀狀态。我們從沒改變過backgroundColor屬性,是以圖層就傳回到原始的顔色。

(2)CAKeyframeAnimation是另一種UIKit沒有暴露但功能強大的類。CAKeyframeAnimation提供了關鍵節點的幀,然後Core Animation在非關鍵位置對每幀之間進行自動處理

(3)CAAnimationGroup可以把這些動畫組合在一起形成一個動畫組。

(4)過渡(CATransition)

屬性動畫隻對圖層的可動畫屬性起作用,是以如果要改變一個不能動畫的屬性(比如圖檔),或者從層級關系中添加或者移除圖層,屬性動畫将不起作用。于是就有了過渡。過渡并不像屬性動畫那樣平滑地在兩個值之間做動畫,而是影響到整個圖層的變化。過渡動畫首先展示之前的圖層外觀,然後通過一個交換過渡到新的外觀。CATransition隻提供了四種預設動畫類型,太少了。但是蘋果通過UIView +transitionFromView:toView:duration:options:completion:和+transitionWithView:duration:options:animations:方法提供了Core Animation的過渡特性。UIView過渡方法中options參數可以由如下常量指定:

UIViewAnimationOptionTransitionFlipFromLeft 

UIViewAnimationOptionTransitionFlipFromRight

UIViewAnimationOptionTransitionCurlUp 

UIViewAnimationOptionTransitionCurlDown

UIViewAnimationOptionTransitionCrossDissolve 

UIViewAnimationOptionTransitionFlipFromTop 

UIViewAnimationOptionTransitionFlipFromBotto

小例子:用renderInContext:建立自定義過渡效果

@implementation ViewController

- (IBAction)performTransition

{

    // 截圖

    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, 0.0);

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *coverImage = UIGraphicsGetImageFromCurrentImageContext();

    // 插入截圖

    UIView *coverView = [[UIImageView alloc] initWithImage:coverImage];

    coverView.frame = self.view.bounds;

    [self.view addSubview:coverView];

    // 更新視圖(設定一個随機的背景色)

    CGFloat red = arc4random() / (CGFloat)INT_MAX;

    CGFloat green = arc4random() / (CGFloat)INT_MAX;

    CGFloat blue = arc4random() / (CGFloat)INT_MAX;

    self.view.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];

    // 做自定義動畫

    [UIView animateWithDuration:1.0 animations:^{

        // 放縮旋轉和淡入淡出

        CGAffineTransform transform = CGAffineTransformMakeScale(0.01, 0.01);

        transform = CGAffineTransformRotate(transform, M_PI_2);

        coverView.transform = transform;

        coverView.alpha = 0.0;

    } completion:^(BOOL finished) {

        // 動畫結束移除覆寫層

        [coverView removeFromSuperview];

    }];

@end

Core Animation 學習筆記(二)

最後附上我看過的一本關于Core Animation的書籍《Core Animation Advanced Technology》,還要感謝“代碼蘿蔔”的部落格Core Animation Advanced Technique 學習筆記 - 代碼蘿蔔