1.CAShapeLayer
CAShapeLayer是一個(gè)通過矢量圖形而不是bitmap來(lái)繪制的圖層子類季眷。你指定諸如顏色和線寬等屬性,用CGPath來(lái)定義想要繪制的圖形夯膀,最后CAShapeLayer就自動(dòng)渲染出來(lái)了
相比Core Graphics之下旧找,使用CAShapeLayer有以下一些優(yōu)點(diǎn):
渲染快速。CAShapeLayer使用了硬件加速吹艇,繪制同一圖形會(huì)比用Core Graphics快很多惰蜜。
高效使用內(nèi)存。一個(gè)CAShapeLayer不需要像普通CALayer一樣創(chuàng)建一個(gè)寄宿圖形受神,所以無(wú)論有多大抛猖,都不會(huì)占用太多的內(nèi)存。
不會(huì)被圖層邊界剪裁掉鼻听。一個(gè)CAShapeLayer可以在邊界之外繪制财著。你的圖層路徑不會(huì)像在使用Core Graphics的普通CALayer一樣被剪裁掉(如我們?cè)诘诙滤姡?/p>
不會(huì)出現(xiàn)像素化。當(dāng)你給CAShapeLayer做3D變換時(shí)撑碴,它不像一個(gè)有寄宿圖的普通圖層一樣變得像素化撑教。
CAShapeLayer通過CGPath來(lái)表示形狀∽硗兀可以控制屬性伟姐,lineWidth,lineCap廉嚼,lineJoin玫镐,不過這些形狀都只能是同一樣的,一個(gè)layer只能設(shè)置一種怠噪。
創(chuàng)建帶圓角和直角的圖恐似,創(chuàng)建圓角矩形其實(shí)就是人工繪制單獨(dú)的直線和弧度,但是事實(shí)上UIBezierPath有自動(dòng)繪制圓角矩形的構(gòu)造方法
- (void)setCornerWithFlaot:(CGFloat)corner byRoundingCorners:(UIRectCorner)corners{
//define path
CGRect rect = self.bounds;
CGSize radii = CGSizeMake(corner, corner);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:corners
cornerRadii:radii];
//define layer
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = self.bounds;
shapeLayer.path = path.CGPath;
self.layer.mask = shapeLayer;
}
2.CATransformLayer
CATransformLayerk可以將CALayer的構(gòu)造的3D圖鏈接起來(lái)放入同一3D空間中
3.CAGradientLayer
CAGradientLayer是用來(lái)生成兩種或更多顏色平滑漸變的傍念。但是CAGradientLayer的真正好處在于繪制使用了硬件加速矫夷。這些漸變色彩放在一個(gè)數(shù)組中,并賦給colors屬性
- (void)viewDidLoad
{
[super viewDidLoad];
//create gradient layer and add it to our container view
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.containerView.bounds;
[self.containerView.layer addSublayer:gradientLayer];
//set gradient colors
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor];
//set gradient start and end points
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(1, 1);
}
默認(rèn)情況下憋槐,這些顏色在空間上均勻地被渲染双藕,但是我們可以用locations屬性來(lái)調(diào)整空間。locations屬性是一個(gè)浮點(diǎn)數(shù)值的數(shù)組(以NSNumber包裝)阳仔。這些浮點(diǎn)數(shù)定義了colors屬性中每個(gè)不同顏色的位置忧陪,同樣的,也是以單位坐標(biāo)系進(jìn)行標(biāo)定。0.0代表著漸變的開始嘶摊,1.0代表著結(jié)束延蟹。
//set locations
gradientLayer.locations = @[@0.0, @0.25, @0.5];
4.CAReplicatorLayer
CAReplicatorLayer的目的是為了高效生成許多相似的圖層。
CAReplicatorLayer真正應(yīng)用到實(shí)際程序上的場(chǎng)景比如:一個(gè)游戲中導(dǎo)彈的軌跡云叶堆,或者粒子爆炸(盡管iOS 5已經(jīng)引入了CAEmitterLayer阱飘,它更適合創(chuàng)建任意的粒子效果)。除此之外虱颗,還有一個(gè)實(shí)際應(yīng)用是:反射沥匈。
指定一個(gè)繼承于UIView的ReflectionView,它會(huì)自動(dòng)產(chǎn)生內(nèi)容的反射效果
@implementation ReflectionView
+ (Class)layerClass
{
return [CAReplicatorLayer class];
}
- (void)setUp
{
//configure replicator
CAReplicatorLayer *layer = (CAReplicatorLayer *)self.layer;
layer.instanceCount = 2;
//move reflection instance below original and flip vertically
CATransform3D transform = CATransform3DIdentity;
CGFloat verticalOffset = self.bounds.size.height + 2;
transform = CATransform3DTranslate(transform, 0, verticalOffset, 0);
transform = CATransform3DScale(transform, 1, -1, 0);
layer.instanceTransform = transform;
//reduce alpha of reflection layer
layer.instanceAlphaOffset = -0.6;
}
- (id)initWithFrame:(CGRect)frame
{
//this is called when view is created in code
if ((self = [super initWithFrame:frame])) {
[self setUp];
}
return self;
}
- (void)awakeFromNib
{
//this is called when view is created from a nib
[self setUp];
}
@end
5.CATiledLayer
CATiledLayer很好地和UIScrollView集成在一起忘渔。除了設(shè)置圖層和滑動(dòng)視圖邊界以適配整個(gè)圖片大小高帖,我們真正要做的就是實(shí)現(xiàn)-drawLayer:inContext:方法,當(dāng)需要載入新的小圖時(shí)辨萍,CATiledLayer就會(huì)調(diào)用到這個(gè)方法棋恼。
#import "ViewController.h" ? ?
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//add the tiled layer
CATiledLayer *tileLayer = [CATiledLayer layer];
tileLayer.frame = CGRectMake(0, 0, 2048, 2048);
tileLayer.delegate = self;
tileLayer.contentsScale = [UIScreen mainScreen].scale;
[self.scrollView.layer addSublayer:tileLayer];
//configure the scroll view
self.scrollView.contentSize = tileLayer.frame.size;
//draw layer
[tileLayer setNeedsDisplay];
}
- (void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx
{
//determine tile coordinate
CGRect bounds = CGContextGetClipBoundingBox(ctx);
CGFloat scale = [UIScreen mainScreen].scale;
NSInteger x = floor(bounds.origin.x / layer.tileSize.width* scale);
NSInteger y = floor(bounds.origin.y / layer.tileSize.height* scale);
//load tile image
NSString *imageName = [NSString stringWithFormat: @"Snowman_%02i_%02i", x, y];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"jpg"];
UIImage *tileImage = [UIImage imageWithContentsOfFile:imagePath];
//draw tile
UIGraphicsPushContext(ctx);
[tileImage drawInRect:bounds];
UIGraphicsPopContext();
}
@end
CAEmitterLayer
蘋果引入了一個(gè)新的CALayer子類叫做CAEmitterLayer。CAEmitterLayer是一個(gè)高性能的粒子引擎锈玉,被用來(lái)創(chuàng)建實(shí)時(shí)例子動(dòng)畫如:煙霧,火义起,雨等等這些效果拉背。
AVPlayerLayer
AVPlayerLayer是用來(lái)在iOS上播放視頻的。他是高級(jí)接口例如MPMoivePlayer的底層實(shí)現(xiàn)默终,提供了顯示視頻的底層控制椅棺。AVPlayerLayer的使用相當(dāng)簡(jiǎn)單:你可以用+playerLayerWithPlayer:方法創(chuàng)建一個(gè)已經(jīng)綁定了視頻播放器的圖層,或者你可以先創(chuàng)建一個(gè)圖層齐蔽,然后用player屬性綁定一個(gè)AVPlayer實(shí)例两疚。
- (void)viewDidLoad
{
[super viewDidLoad];
//get video URL
NSURL *URL = [[NSBundle mainBundle] URLForResource:@"Ship" withExtension:@"mp4"];
//create player and player layer
AVPlayer *player = [AVPlayer playerWithURL:URL];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
//set player layer frame and attach it to our view
playerLayer.frame = self.containerView.bounds;
[self.containerView.layer addSublayer:playerLayer];
//play the video
[player play];
}
因?yàn)锳VPlayerLayer是CALayer的子類,它繼承了父類的所有特性含滴。我們并不會(huì)受限于要在一個(gè)矩形中播放視頻诱渤;清單6.16演示了在3D,圓角谈况,有色邊框勺美,蒙板,陰影等效果(見圖6.17).
- (void)viewDidLoad
{
...
//set player layer frame and attach it to our view
playerLayer.frame = self.containerView.bounds;
[self.containerView.layer addSublayer:playerLayer];
//transform layer
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0 / 500.0;
transform = CATransform3DRotate(transform, M_PI_4, 1, 1, 0);
playerLayer.transform = transform;
//add rounded corners and border
playerLayer.masksToBounds = YES;
playerLayer.cornerRadius = 20.0;
playerLayer.borderColor = [UIColor redColor].CGColor;
playerLayer.borderWidth = 5.0;
//play the video
[player play];
}