書籍是人類進(jìn)步的階梯
總覽思維導(dǎo)圖

一、圖層樹
1.1.contents
簡(jiǎn)介:(id類型),雖然是id類型但如果給contents賦的不是CGImage,那么得到的圖層將是空白的。
layer.contents = (__bridge id)image.CGImage;注意:在加載圖片時(shí)為了適應(yīng)視圖,我們一般這么處理:
view.contentMode = UIViewContentModeScaleAspectFit;
但在CALayer與contentMode對(duì)應(yīng)的屬性叫做contentsGravity:
self.layerView.layer.contentsGravity = kCAGravityResizeAspect;
1.2 contentsScale
- 寄宿圖的像素尺寸和視圖大小的比例,默認(rèn)情況下它是一個(gè)值為1.0的浮點(diǎn)數(shù):當(dāng)用代碼來處理寄宿圖的時(shí)候,一定要記住要手動(dòng)的設(shè)置圖層的contentsScale屬性,否則,你的圖片在Retina設(shè)備上就顯示得不正確啦。代碼如下:
layer.contentsScale = [UIScreen mainScreen].scale;
1.3 maskToBounds
- UIView有一個(gè)叫做clipsToBounds的屬性可以用來決定是否顯示超出邊界的內(nèi)容,CALayer對(duì)應(yīng)的屬性叫做masksToBounds
1.4 contentsRect
- 默認(rèn)的contentsRect是{0, 0, 1, 1},這意味著整個(gè)寄宿圖默認(rèn)都是可見的,如果設(shè)置{0,0,0.5,0.5},那只顯示左上角部分(整體的1/4部分)

1.5 contentsCenter
-
其實(shí)是一個(gè)CGRect,它定義了一個(gè)固定的邊框和一個(gè)
在圖層上可拉伸的區(qū)域。默認(rèn)情況下,contentsCenter是{0, 0, 1, 1},這意
味著如果大?。ㄓ蒫onttensGravity決定)改變了,那么寄宿圖將會(huì)均勻地拉
伸開。但是如果我們?cè)黾釉c(diǎn)的值并減小尺寸。我們會(huì)在圖片的周圍創(chuàng)造
一個(gè)邊框。圖2.9展示了contentsCenter設(shè)置為{0.25, 0.25, 0.5, 0.5}的效果。
contentsCenter.png
1.6 -drawRect:方法:
- 當(dāng)視圖在屏幕上出現(xiàn)的時(shí)候 -drawRect:方法就會(huì)被自動(dòng)調(diào)用;
- 調(diào)用了-setNeedsDisplay方法時(shí),-drawRect:方法會(huì)被調(diào)用;
二、圖層幾何學(xué)
2.1 frame、bounds、position
-
當(dāng)對(duì)圖層做變換的時(shí)候,比如旋轉(zhuǎn)或者縮放,frame實(shí)際上代表了覆蓋在圖層旋轉(zhuǎn)之后的整個(gè)軸對(duì)齊的矩形區(qū)域,也就是說frame的寬高可能和bounds的寬高不再一致了
frame
2.2 錨點(diǎn)anchorPoint
- anchorPoint是用來移動(dòng)圖層的把柄。anchorPoint用單位坐標(biāo)來描述,也就是圖層的相對(duì)坐標(biāo),圖層左上角是{0, 0},右下角是{1, 1},因此默認(rèn)坐標(biāo)是{0.5, 0.5}
2.3zPosition
- 在大多數(shù)情況下其實(shí)并不常用。zPosition最實(shí)用的功能就是改變圖層的顯示順序了。通過增加圖層的zPosition,就可以把圖層向相機(jī)方向前置,于是它就在所有其他圖層的前面了(或者至少是小于它的zPosition值的圖層的前面)。
2.4 -containsPoint
- 接受一個(gè)在本圖層坐標(biāo)系下的CGPoint,如果這個(gè)點(diǎn)在圖層frame范圍內(nèi)就返回YES。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint point = [[touches anyObject] locationInView:self.view];
point = [self.layerView.layer convertPoint:point fromLayer:self.view.layer];
//get layer using containsPoint:
if ([self.layerView.layer containsPoint:point]) {
//convert point to blueLayer’s coordinates
point = [self.blueLayer convertPoint:point fromLayer:self.layerView.layer];
if ([self.blueLayer containsPoint:point]) {
// your code
} else {
// your other code
}
}
}
2.5 -hitTest
- 方法接受一個(gè)CGPoint類型參數(shù),而不是BOOL類型,它返回圖層本身,或者包含這個(gè)坐標(biāo)點(diǎn)的葉子節(jié)點(diǎn)圖層:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//get touch position
CGPoint point = [[touches anyObject] locationInView:self.view];
//get touched layer
CALayer *layer = [self.layerView.layer hitTest:point];
//get layer using hitTest
if (layer == self.blueLayer) {
// your code
} else if (layer == self.layerView.layer) {
// your other code
}
}
三、專用圖層CALayer
3.1 CAShapeLayer
- 使用CAShapeLayer的優(yōu)點(diǎn):
- 渲染快速。CAShapeLayer使用了硬件加速,繪制同一圖形會(huì)比用Core Graphics快很多;
- 高效使用內(nèi)存。一個(gè)CAShapeLayer不需要像普通CALayer一樣創(chuàng)建一個(gè)寄宿圖形,所以無論有多大,都不會(huì)占用太多的內(nèi)存;
- 不會(huì)被圖層邊界剪裁掉。一個(gè)CAShapeLayer可以在邊界之外繪制。
- 不會(huì)出現(xiàn)像素化。當(dāng)你給CAShapeLayer做3D變換時(shí),它不像一個(gè)有寄宿圖的普通圖層一樣變得像素化。
1.CAShapeLayer可以用來繪制所有能夠通過CGPath來表示的形狀。
2.CAShapeLayer屬性是CGPathRef類型
- 繪制圓角:( 需求:三個(gè)圓角,一個(gè)直角)
CGRect rect = CGRectMake(50, 50, 100, 100);
CGSize radii = CGSizeMake(20, 20);
UIRectCorner corners = UIRectCornerTopRight | UIRectCornerBottomRight | UIRectCornerBottomLeft;
//create path
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];
3.2 CATextLayer
- CATextLayer也要比UILabel渲染得快得多。很少有人知道在iOS 6及之前的版本,UILabel其實(shí)是通過WebKit來實(shí)現(xiàn)繪制的,這樣就造成了當(dāng)有很多文字的時(shí)候就會(huì)有極大的性能壓力。
- CATextLayer使用了Core text,并且渲染得非??臁?梢試L試封裝一個(gè)CATextLayer用于替換UILabel
UILabel的替代品
- 使用CATextLayer來封裝一個(gè)UILabel的子類
#import "LayerLabel.h"
@implementation LayerLabel
+ (Class)layerClass
{
//this makes our label create a CATextLayer //instead of a regular CALayer for its backing layer
return [CATextLayer class];
}
- (CATextLayer *)textLayer
{
return (CATextLayer *)self.layer;
}
- (void)setUp
{
//set defaults from UILabel settings
self.text = self.text;
self.textColor = self.textColor;
self.font = self.font;
//we should really derive these from the UILabel settings too
//but that's complicated, so for now we'll just hard-code them
[self textLayer].alignmentMode = kCAAlignmentJustified;
[self textLayer].wrapped = YES;
[self.layer display];
}
- (id)initWithFrame:(CGRect)frame
{
//called when creating label programmatically
if (self = [super initWithFrame:frame]) {
[self setUp];
}
return self;
}
- (void)awakeFromNib
{
//called when creating label using Interface Builder
[self setUp];
}
- (void)setText:(NSString *)text
{
super.text = text;
//set layer text
[self textLayer].string = text;
}
- (void)setTextColor:(UIColor *)textColor
{
super.textColor = textColor;
//set layer text color
[self textLayer].foregroundColor = textColor.CGColor;
}
- (void)setFont:(UIFont *)font
{
super.font = font;
//set layer font
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
[self textLayer].font = fontRef;
[self textLayer].fontSize = font.pointSize;
CGFontRelease(fontRef);
}
@end
3.3 CATransformLayer
- CATransformLayer不同于普通的CALayer,因?yàn)樗荒茱@示它自己的內(nèi)容。只有當(dāng)存在了一個(gè)能作用域子圖層的變換它才真正存在。CATransformLayer并不平面化它的子圖層,所以它能夠用于構(gòu)造一個(gè)層級(jí)的3D結(jié)構(gòu)
3.4 CATiledLayer
- CATiledLayer為載入大圖造成的性能問題提供了一個(gè)解決方案:將大圖分解成小片然后將他們單獨(dú)按需載入
3.5 CAGradientLayer
- CAGradientLayer是用來生成兩種或更多顏色平滑漸變的。用Core Graphics復(fù)制一個(gè)CAGradientLayer并將內(nèi)容繪制到一個(gè)普通圖層的寄宿圖也是有可能的,但是CAGradientLayer的真正好處在于繪制使用了硬件加速。
3.6 CAReplicatorLayer:(反射效果)
- CAReplicatorLayer的目的是為了高效生成許多相似的圖層。它會(huì)繪制一個(gè)或多個(gè)圖層的子圖層,并在每個(gè)復(fù)制體上應(yīng)用不同的變換。
3.7 CAEmitterLayer(粒子、火焰特效)
- 簡(jiǎn)介CAEmitterLayer是一個(gè)高性能的粒子引擎,被用來創(chuàng)建實(shí)時(shí)例子動(dòng)畫如:煙霧,火,雨等等這些效果。
-
CAEmitterCell:
CAEmitterLayer看上去像是許多CAEmitterCell的容器,這些CAEmitierCell定義了一個(gè)例子效果。你將會(huì)為不同的例子效果定義一個(gè)或多個(gè)CAEmitterCell作為模版,同時(shí)CAEmitterLayer負(fù)責(zé)基于這些模版實(shí)例化一個(gè)粒子流。一個(gè)CAEmitterCell類似于一個(gè)CALayer:它有一個(gè)contents屬性可以定義為一個(gè)CGImage。
CAEMitterCell的屬性
- 這種粒子的某一屬性的初始值。比如,color屬性指定了一個(gè)可以混合圖片內(nèi)容顏色的混合色。在示例中,我們將它設(shè)置為桔色。
- 例子某一屬性的變化范圍。比如emissionRange屬性的值是2π,這意味著例子可以從360度任意位置反射出來。如果指定一個(gè)小一些的值,就可以創(chuàng)造出一個(gè)圓錐形。
- 指定值在時(shí)間線上的變化。比如,在示例中,我們將alphaSpeed設(shè)置為-0.4,就是說例子的透明度每過一秒就是減少0.4,這樣就有發(fā)射出去之后逐漸消失的效果。
- preservesDepth:是否將3D例子系統(tǒng)平面化到一個(gè)圖層(默認(rèn)值)或者可以在3D空間中混合其他的圖層。
- renderMode:控制著在視覺上粒子圖片是如何混合的。你可能已經(jīng)注意到了示例中我們把它設(shè)置為kCAEmitterLayerAdditive,它實(shí)現(xiàn)了這樣一個(gè)效果:合并例子重疊部分的亮度使得看上去更亮。
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *containerView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CAEmitterLayer *emitter = [CAEmitterLayer layer];
emitter.frame = self.containerView.bounds;
[self.containerView.layer addSublayer:emitter];
//configure emitter
emitter.renderMode = kCAEmitterLayerAdditive;
emitter.emitterPosition = CGPointMake(emitter.frame.size.width / 2.0, emitter.frame.size.height / 2.0);
//create a particle template
CAEmitterCell *cell = [[CAEmitterCell alloc] init];
cell.contents = (__bridge id)[UIImage imageNamed:@"Spark.png"].CGImage;
cell.birthRate = 150;
cell.lifetime = 5.0;
cell.color = [UIColor colorWithRed:1 green:0.5 blue:0.1 alpha:1.0].CGColor;
cell.alphaSpeed = -0.4;
cell.velocity = 50;
cell.velocityRange = 50;
cell.emissionRange = M_PI * 2.0;
//add particle template to emitter
emitter.emitterCells = @[cell];
}
@end
3.8 CAEAGLLayer
- 用來顯示任意的OpenGL圖形,一般用不到。
3.9 AVPlayerLayer
- AVPlayerLayer是CALayer的子類,它繼承了父類的所有特性,主要用于視頻播放。
4.0 CAScrollLayer
- UIView中的UIScrollView的底層封裝。
四、視覺效果
4.1 圓角
- conrnerRadius:控制著圖層角的曲率。(只影響背景顏色而不影響背景圖片或是子圖層),一般和masksToBounds配合著使用。
- borderWidth:定義邊框粗細(xì)
- borderColor:邊框的顏色
4.2 陰影
- shadowOpacity:0.0(不可見)和1.0(完全不透明)之間的浮點(diǎn)數(shù);
- shadowColor:控制陰影的顏色;
- shadowOffset:控制陰影的方向和距離。默認(rèn)值是 {0, -3},意即陰影相對(duì)于Y軸有3個(gè)點(diǎn)的向上位移;
- shadowRadius:控制著陰影的模糊度,當(dāng)值為0時(shí),陰影和視圖有非常確定的邊界線。值越大,邊界線看上去就會(huì)越來越模糊和自然;
- shadowPath:一個(gè)CGPathRef類型(一個(gè)指向CGPath的指針)。我們可以通過這個(gè)屬性單獨(dú)于圖層形狀之外指定陰影的形狀;
- mask:mask圖層比父圖層要小,只有在mask圖層里面的內(nèi)容才是它關(guān)心的,除此以外的一切都會(huì)被隱藏起來。代碼演示:
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//create mask layer
CALayer *maskLayer = [CALayer layer];
maskLayer.frame = self.layerView.bounds;
UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];
maskLayer.contents = (__bridge id)maskImage.CGImage;
//apply mask to image layer
self.imageView.layer.mask = maskLayer;
}
@end
效果:

4.3拉伸過濾:
view.layer.magnificationFilter = kCAFilterNearest;
4.4 組透明
- 透明度會(huì)疊加,即當(dāng)一個(gè)控件有子控件時(shí),設(shè)置父控件的透明度(UIView對(duì)應(yīng)alpha、CALayer對(duì)應(yīng)opacity),子控件的透明度也會(huì)被影響。設(shè)置CALayer的一個(gè)叫做shouldRasterize屬性來實(shí)現(xiàn)組透明的效果,如果它被設(shè)置為YES,在應(yīng)用透明度之前,圖層及其子圖層都會(huì)被整合成一個(gè)整體的圖片,這樣就沒有透明度混合的問題了:
view.layer.shouldRasterize = YES;
view.layer.rasterizationScale = [UIScreen mainScreen].scale;
五、變換
5.1 仿射變換CGAffineTransform(2D變換)
5.1.1 原理:
1. UIView的transform屬性是一個(gè)CGAffineTransform類型,用于在二維空間做旋轉(zhuǎn),縮放和平移;
2. CALayer對(duì)應(yīng)于UIView的transform屬性叫做affineTransform;
3. CALayer同樣也有一個(gè)transform屬性,但它的類型是CATransform3D。
5.1.2 主要方法:
CGAffineTransformMakeRotation(CGFloat angle); //旋轉(zhuǎn)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy); //縮放
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty); //平移
5.1.3 混合變換:CGAffineTransformIdentity
// 需求:先縮小50%,再旋轉(zhuǎn)30度,最后向右移動(dòng)200個(gè)像素
- (void)viewDidLoad
{
[super viewDidLoad];
//create a new transform
CGAffineTransform transform = CGAffineTransformIdentity;
//scale by 50%
transform = CGAffineTransformScale(transform, 0.5, 0.5);
//rotate by 30 degrees
transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
//translate by 200 points
transform = CGAffineTransformTranslate(transform, 200, 0);
//apply transform to layer
self.layerView.layer.affineTransform = transform;
}
3D變換CATransform3D
5.2.1 主要方法:
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z); //旋轉(zhuǎn)
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz); //縮放
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz); //平移
5.2.2 透視投影:m34
m34的默認(rèn)值是0,我們可以通過設(shè)置m34為-1.0 / d來應(yīng)用透視效果,d代表了想象中視角相機(jī)和屏幕之間的距離,通常500-1000就已經(jīng)很好了。
5.2.3 滅點(diǎn)
當(dāng)在透視角度繪圖的時(shí)候,遠(yuǎn)離相機(jī)視角的物體將會(huì)變小變遠(yuǎn),當(dāng)遠(yuǎn)離到一個(gè)極限距離,它們可能就縮成了一個(gè)點(diǎn),于是所有的物體最后都匯聚消失在同一個(gè)點(diǎn)(在現(xiàn)實(shí)中,這個(gè)點(diǎn)通常是視圖的中心)
- sublayerTransform:它也是CATransform3D類型,它會(huì)影響到所有的子圖層。這意味著你可以一次性對(duì)包含這些圖層的容器做變換,于是所有的子圖層都自動(dòng)繼承了這個(gè)變換方法:
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic, weak) IBOutlet UIView *layerView1;
@property (nonatomic, weak) IBOutlet UIView *layerView2;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//apply perspective transform to container
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500.0;
self.containerView.layer.sublayerTransform = perspective;
//rotate layerView1 by 45 degrees along the Y axis
CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
self.layerView1.layer.transform = transform1;
//rotate layerView2 by 45 degrees along the Y axis
CATransform3D transform2 = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);
self.layerView2.layer.transform = transform2;
}
六、隱式動(dòng)畫
事務(wù)(CATransaction)
- 事務(wù)實(shí)際上是Core Animation用來包含一系列屬性動(dòng)畫集合的機(jī)制,任何用指定事務(wù)去改變可以做動(dòng)畫的圖層屬性都不會(huì)立刻發(fā)生變化,而是當(dāng)事務(wù)一旦提交的時(shí)候開始用一個(gè)動(dòng)畫過渡到新值
主要用法:
[CATransaction begin]; // 入棧
[CATransaction commit]; //出棧
+setAnimationDuration: //設(shè)置當(dāng)前事務(wù)的動(dòng)畫時(shí)間
+animationDuration // 獲取值(默認(rèn)0.25秒)
[CATransaction setDisableActions:YES]; //對(duì)所有屬性關(guān)閉隱式動(dòng)畫
隱式動(dòng)畫如何實(shí)現(xiàn):
- 圖層首先檢測(cè)它是否有委托,并且是否實(shí)現(xiàn)CALayerDelegate協(xié)議指定的-actionForLayer:forKey方法。如果有,直接調(diào)用并返回結(jié)果。
- 如果沒有委托,或者委托沒有實(shí)現(xiàn)-actionForLayer:forKey方法,圖層接著檢查包含屬性名稱對(duì)應(yīng)行為映射的actions字典。
- 如果actions字典沒有包含對(duì)應(yīng)的屬性,那么圖層接著在它的style字典接著搜索屬性名。
- 最后,如果在style里面也找不到對(duì)應(yīng)的行為,那么圖層將會(huì)直接調(diào)用定義了每個(gè)屬性的標(biāo)準(zhǔn)行為的-defaultActionForKey:方法。
所以一輪完整的搜索結(jié)束之后,-actionForKey:要么返回空(這種情況下將不會(huì)有動(dòng)畫發(fā)生),要么是CAAction協(xié)議對(duì)應(yīng)的對(duì)象,最后CALayer拿這個(gè)結(jié)果去對(duì)先前和當(dāng)前的值做動(dòng)畫。
七、顯式動(dòng)畫
7.1 關(guān)鍵幀動(dòng)畫(CAKeyframeAnimation)
和CABasicAnimation類似,CAKeyframeAnimation同樣是CAPropertyAnimation的一個(gè)子類,它依然作用于單一的一個(gè)屬性,但是和CABasicAnimation不一樣的是,它不限制于設(shè)置一個(gè)起始和結(jié)束的值,而是可以根據(jù)一連串隨意的值來做動(dòng)畫。
- 關(guān)鍵幀起源于傳動(dòng)動(dòng)畫,意思是指主導(dǎo)的動(dòng)畫在顯著改變發(fā)生時(shí)重繪當(dāng)前幀(也就是關(guān)鍵幀),每幀之間剩下的繪制(可以通過關(guān)鍵幀推算出)將由熟練的藝術(shù)家來完成。CAKeyframeAnimation也是同樣的道理:你提供了顯著的幀,然后Core Animation在每幀之間進(jìn)行插入。
代碼:
- (void)viewDidLoad
{
[super viewDidLoad];
//create a path
...
//create the keyframe animation
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
// 平移動(dòng)畫
animation.keyPath = @"position";
//持續(xù)時(shí)間
animation.duration = 4.0;
// 動(dòng)畫路徑
animation.path = bezierPath.CGPath;
// *圖層將會(huì)根據(jù)曲線的切線自動(dòng)旋轉(zhuǎn)*
animation.rotationMode = kCAAnimationRotateAuto;
[shipLayer addAnimation:animation forKey:nil];
}
八、動(dòng)畫組CAAnimationGroup
- CAAnimationGroup是另一個(gè)繼承于CAAnimation的子類,它添加了一個(gè)animations數(shù)組的屬性,用來組合別的動(dòng)畫。實(shí)例代碼:
- (void)viewDidLoad
{
[super viewDidLoad];
//create a path
UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
[bezierPath moveToPoint:CGPointMake(0, 150)];
[bezierPath addCurveToPoint:CGPointMake(300, 150) controlPoint1:CGPointMake(75, 0) controlPoint2:CGPointMake(225, 300)];
//draw the path using a CAShapeLayer
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.path = bezierPath.CGPath;
pathLayer.fillColor = [UIColor clearColor].CGColor;
pathLayer.strokeColor = [UIColor redColor].CGColor;
pathLayer.lineWidth = 3.0f;
[self.containerView.layer addSublayer:pathLayer];
//add a colored layer
CALayer *colorLayer = [CALayer layer];
colorLayer.frame = CGRectMake(0, 0, 64, 64);
colorLayer.position = CGPointMake(0, 150);
colorLayer.backgroundColor = [UIColor greenColor].CGColor;
[self.containerView.layer addSublayer:colorLayer];
//create the position animation
CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animation];
animation1.keyPath = @"position";
animation1.path = bezierPath.CGPath;
animation1.rotationMode = kCAAnimationRotateAuto;
//create the color animation
CABasicAnimation *animation2 = [CABasicAnimation animation];
animation2.keyPath = @"backgroundColor";
animation2.toValue = (__bridge id)[UIColor redColor].CGColor;
//create group animation
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = @[animation1, animation2];
groupAnimation.duration = 4.0;
//add the animation to the color layer
[colorLayer addAnimation:groupAnimation forKey:nil];
}
九、CATransition(過渡動(dòng)畫)
-
type(動(dòng)畫類型)
- kCATransitionFade (淡入淡出)
- kCATransitionMoveIn(從頂部滑動(dòng)進(jìn)入)
- kCATransitionPush
- kCATransitionReveal
-
subtype(動(dòng)畫方向)
- kCATransitionFromRight
- kCATransitionFromLeft
- kCATransitionFromTop
- kCATransitionFromBottom
在動(dòng)畫過程中取消動(dòng)畫
- (void)removeAnimationForKey:(NSString *)key; // 移除某個(gè)動(dòng)畫
- (void)removeAllAnimations; // 移除所有動(dòng)畫
十、CAMediaTiming協(xié)議
10.1 概念
- CAMediaTiming協(xié)議定義了在一段動(dòng)畫內(nèi)用來控制逝去時(shí)間的屬性的集合,CALayer和CAAnimation都實(shí)現(xiàn)了這個(gè)協(xié)議,所以時(shí)間可以被任意基于一個(gè)圖層或者一段動(dòng)畫的類控制。
10.2 屬性
- duration:CFTimeInterval的類型,對(duì)將要進(jìn)行的動(dòng)畫的一次迭代指定了時(shí)間;
- repeatCount:動(dòng)畫重復(fù)的迭代次數(shù);
- repeatDuration:動(dòng)畫重復(fù)一個(gè)指定的時(shí)間,而不是指定次數(shù);
- autoreverses:(BOOL類型)在每次間隔交替循環(huán)過程中自動(dòng)回放。
10.3 注意
- duration和repeatCount默認(rèn)都是0。但這不意味著動(dòng)畫時(shí)長(zhǎng)為0秒,或者0次,這里的0僅僅代表了“默認(rèn)”,也就是0.25秒和1次;
- 把repeatDuration設(shè)置為INFINITY,于是動(dòng)畫無限循環(huán)播放,設(shè)置repeatCount為INFINITY也有同樣的效果。
- repeatCount和repeatDuration可能會(huì)相互沖突,所以你只要對(duì)其中一個(gè)指定非零值.
10.4 相對(duì)時(shí)間
- beginTime:指定了動(dòng)畫開始之前的的延遲時(shí)間。這里的延遲從動(dòng)畫添加到可見圖層的那一刻開始測(cè)量,默認(rèn)是0(就是說動(dòng)畫會(huì)立刻執(zhí)行)
- speed:是一個(gè)時(shí)間的倍數(shù),默認(rèn)1.0,減少它會(huì)減慢圖層/動(dòng)畫的時(shí)間,增加它會(huì)加快速度。如果2.0的速度,那么對(duì)于一個(gè)duration為1的動(dòng)畫,實(shí)際上在0.5秒的時(shí)候就已經(jīng)完成了.
- timeOffset:增加timeOffset只是讓動(dòng)畫快進(jìn)到某一點(diǎn),例如,對(duì)于一個(gè)持續(xù)1秒的動(dòng)畫來說,設(shè)置timeOffset為0.5意味著動(dòng)畫將從一半的地方開始.
基于定時(shí)器的動(dòng)畫
NSTimer并不準(zhǔn)確的原因:
iOS上的每個(gè)線程都管理了一個(gè)NSRunloop,通過一個(gè)循環(huán)來完成一些任務(wù)列表。當(dāng)你設(shè)置一個(gè)NSTimer,他會(huì)被插入到當(dāng)前任務(wù)列表中,然后直到指定時(shí)間過去之后才會(huì)被執(zhí)行。但是何時(shí)啟動(dòng)定時(shí)器并沒有一個(gè)時(shí)間上限,而且它只會(huì)在列表中上一個(gè)任務(wù)完成之后開始執(zhí)行。這通常會(huì)導(dǎo)致有幾毫秒的延遲,但是如果上一個(gè)任務(wù)過了很久才完成就會(huì)導(dǎo)致延遲很長(zhǎng)一段時(shí)間.
性能優(yōu)化(待完善)
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

