iOS Core Animation Advanced Techniques-专用图层
上五章节:
这篇随笔主要介绍有关专用图层。
专用图层都属于CALayer的子类:
- CAShapeLayer:
- 通过CGPath表示的任何矢量图形而不是bitmap来绘制图层子类,类似用Core Graphics向CALayer的内容绘制一个路径渲染出图形,但是使用CAShapeLayer有以下优点:
1.渲染快速,因为使用了硬件加速
2.高效使用内存,因为不需要像普通CALayer一样创建一个寄宿图形
3.不会被图层边界裁剪,不像使用Core Graphics在普通CALayer中绘图会被边界裁剪内容
4.不会出现像素化,给CAShapeLayer做3D变换时不像一个有寄宿图的普通CALayer一样变得像素化
-
- 通过CGPath绘制的形状不一定要闭合,可以在一个图层绘制好几个不同的形状,
- 通过控制属性如
- lineWith:线宽
- lineCap:线条结尾的样子
- lineJoin:线条之间的结合点的样子
-
- 使用例子:
- //这里使用的是UIBezierPath绘制的路径,不用考虑人工释放CGPath
- UIBezierPath *path=[[UIBezierPath alloc]init];
- [path moveToPoint:CGPointMake(175,100)];
- [path addArcWithCenter:CGPointMake(150,100)radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
- [path moveToPoint:CGPointMake(150, 125)];
- [path addLineToPoint:CGPointMake(150, 175)];
- [path addLineToPoint:CGPointMake(125, 225)];
- [path moveToPoint:CGPointMake(150, 175)];
- [path addLineToPoint:CGPointMake(175, 225)];
- [path moveToPoint:CGPointMake(100, 150)];
- [path addLineToPoint:CGPointMake(200, 150)];
- CAShapeLayer *shapeLayer=[CAShapeLayer layer];
- shapeLayer.strokeColor=[UIColor redColor].CGColor;
- shapeLayer.fillColor=[UIColor clearColor].CGColor;
- shapeLayer.lineWidth=5;
- shapeLayer.lineJoin=kCALineJoinRound;
- shapeLayer.lineCap=kCALineCapRound;
- shapeLayer.path=path.CGPath;
- [myView.layer addSublayer:shapeLayer];
- 该专用图层还有一个特色就是可以单独指定每一个角的曲率,先用UIBezierPath创建一个指定特定角圆角的路径
- 使用例子:
- 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];
- CAShapeLayer *shapeLayer=[CAShapeLayer layer];
- shapeLayer.strokeColor=[UIColor redColor].CGColor;
- shapeLayer.fillColor=[UIColor clearColor].CGColor;
- shapeLayer.lineWidth=5;
- shapeLayer.lineJoin=kCALineJoinRound;
- shapeLayer.lineCap=kCALineCapRound;
- shapeLayer.path=path.CGPath;
- [myView.layer addSublayer:shapeLayer];
- 使用例子:
- CATextLayer:
- 以图层的形式包含了UILabel几乎所有的绘制特性,还额外提供了一些新的特性,切比UILabel渲染快
- 使用例子:
- //用CATextLayer来显示一些文字
- CATextLayer *textLayer=[CATextLayer layer];
- textLayer.frame=myView.bounds;
- [myView.layer addSublayer:textLayer];
- textLayer.foregroundColor=[UIColor blackColor].CGColor;
- textLayer.alignmentMode=kCAAlignmentJustified;
- textLayer.wrapped=YES;
- UIFont *font=[UIFont systemFontOfSize:15];
- CFStringRef fontName=(__bridge CFStringRef)font.fontName;
- CGFontRef fontRef=CGFontCreateWithFontName(fontName);
- textLayer.font=fontRef;
- textLayer.fontSize=font.pointSize;
- CGFontRelease(fontRef);
- NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ lobortis";
- textLayer.string=text;
- textLayer.contentsScale=[UIScreen mainScreen].scale;
- CATransformLayer:
- 不同于普通的CALayer,因为不能显示自己的内容,只有当存在了一个能作用于子图层的变换才真正存在
- 不平面化它的子图层
- 使用例子:
- -(CALayer *)faceWithTransform:(CATransform3D)transform{
- CALayer *face=[CALayer layer];
- face.frame=CGRectMake(-50,-50,100,100);
- CGFloat red = (rand() / (double)INT_MAX);
- CGFloat green = (rand() / (double)INT_MAX);
- CGFloat blue = (rand() / (double)INT_MAX);
- face.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
- face.transform = transform;
- return face;
- }
- -(CALayer *)cubeWithTransform:(CAtransform3D)transform{
- CATransformLayer *cube=[CATransformLayer layer];
- CATransform3D ct=CATransform3DMakeTranslation(0,0,50);
- [cube addSublayer:[self faceWithTransform:ct]];//把正常CALayer往CATransformLayer添加让它拥有子图层
- ct = CATransform3DMakeTranslation(50, 0, 0);
- ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);
- [cube addSublayer:[self faceWithTransform:ct]];
- ct = CATransform3DMakeTranslation(0, -50, 0);
- ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);
- [cube addSublayer:[self faceWithTransform:ct]];
- ct = CATransform3DMakeTranslation(0, 50, 0);
- ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);
- [cube addSublayer:[self faceWithTransform:ct]];
- ct = CATransform3DMakeTranslation(-50, 0, 0);
- ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);
- [cube addSublayer:[self faceWithTransform:ct]];
- ct = CATransform3DMakeTranslation(0, 0, -50);
- ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);
- [cube addSublayer:[self faceWithTransform:ct]];
- CGSize containerSize=self.containerView.bounds.size;
- cube.position=CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);
- cube.transform=transform;
- return cube;
- }
- -(void)viewDidLoad{
- [super viewDidLoad];
- CATransform3D pt=CATransform3DIdentity;
- pt.m34=-1.0/500.0;
- containerView.layer.sublayerTransform=pt;
- CATransform3D c1t = CATransform3DIdentity;
- c1t = CATransform3DTranslate(c1t, -100, 0, 0);
- CALayer *cube1 = [self cubeWithTransform:c1t];
- [containerView.layer addSublayer:cube1];
- CATransform3D c2t = CATransform3DIdentity;
- c2t = CATransform3DTranslate(c2t, 100, 0, 0);
- c2t = CATransform3DRotate(c2t, -M_PI_4, 1, 0, 0);
- c2t = CATransform3DRotate(c2t, -M_PI_4, 0, 1, 0);
- CALayer *cube2 = [self cubeWithTransform:c2t];
- [containerView.layer addSublayer:cube2];
- }
- CAGradientLayer:
- 用来生成两种或更多颜色平滑渐变
- 该专用图层使用了硬件加速
- 使用步骤:
1.把切换颜色CGColorRef放到一个数组中
2.把数组赋值给该专用图层的colors属性
3.设置startPoint和sendPoint属性,决定渐变方向,以单位坐标系进行定义,左上角{0,0},右下角{1,1}
-
- 使用例子:
- CAGradientLayer *gradientLayer = [CAGradientLayer layer];
- gradientLayer.frame = containerView.bounds;
- [containerView.layer addSublayer:gradientLayer];
- gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor];
- gradientLayer.startPoint = CGPointMake(0, 0);
- gradientLayer.endPoint = CGPointMake(1, 1);
- 默认颜色在空间上均匀渲染,可以通过locations属性,一个浮点值数组,元素为NSNumber,调整颜色空间
- 0.0表示渐变开始,1.0代表结束,需要确保locations数组大小与colors数组大小相同,不然得到空白的渐变
- 使用例子:
- CAGradientLayer *gradientLayer = [CAGradientLayer layer];
- gradientLayer.frame = containerView.bounds;
- [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);
- 使用例子:
- CAReplicatorLayer:
- 可以高效生成许多相似图层
- instanceCount属性指定图层重复次数
- instanceTransform属性指定一个CATransform3D 3D变换
- 变换是逐步增加的,每个实例相对前一个实例布局
- 使用例子:
- CAReplicatorLayer *replicator=[CAReplicatorLayer layer];
- replicator.frame=containerView.bounds;
- [containerView.layer addSublayer:replicator];
- replicator.instanceCount=10;
- CATransform3D transform=CATransform3DIdentity;
- transform=CATransform3DTranslate(transform,0,200,0);
- transform = CATransform3DRotate(transform, M_PI / 5.0, 0, 0, 1);
- transform = CATransform3DTranslate(transform, 0, -200, 0);
- replicator.instanceTransform = transform;
- replicator.instanceBlueOffset=-0.1;
- replicator.instanceGreenOffset=-0.1;//逐步减少蓝色和绿色通道,我们逐渐将图层颜色转换成了红色
- CALayer *layer = [CALayer layer];
- layer.frame = CGRectMake(100.0f, 100.0f, 100.0f, 100.0f);
- layer.backgroundColor = [UIColor whiteColor].CGColor;
- [replicator addSublayer:layer];
- 一个拥有自带视图倒影效果基于CAReplicatorLayer实现的UIView子类:
- #import "ReflectionView.h"
- #import <QuartzCore/QuartzCore.h>
- @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
- CAScrollLayer
- 在一个独立图层中,想显示一个大图层里面的一小部分,希望能随意滑动,便可使用该专用图层
- -scrollToPoint:方法,自动适应bounds的原点以便图层内容出现在滑动的地方
- 因图层不负责将触摸事件转换为滑动事件,所以既不渲染滚动条,也不实现如滑动反弹等行为
- 使用步骤:
1.用CAScrollLayer作为视图的数组图层
2.创建一个自定义UIView,用UIPanGestureRecognizer实现触摸事件响应
-
- 使用例子:
- #import "ScrollView.h"
- #import <QuartzCore/QuartzCore.h>
- @implementation ScrollView
- + (Class)layerClass
- {
- return [CAScrollLayer class];
- }
- - (void)setUp
- {
- //enable clipping
- self.layer.masksToBounds = YES;
- //attach pan gesture recognizer
- UIPanGestureRecognizer *recognizer = nil;
- recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
- [self addGestureRecognizer:recognizer];
- }
- - (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];
- }
- - (void)pan:(UIPanGestureRecognizer *)recognizer
- {
- //get the offset by subtracting the pan gesture
- //translation from the current bounds origin
- CGPoint offset = self.bounds.origin;
- offset.x -= [recognizer translationInView:self].x;
- offset.y -= [recognizer translationInView:self].y;
- //scroll the layer
- [(CAScrollLayer *)self.layer scrollToPoint:offset];
- //reset the pan gesture translation
- [recognizer setTranslation:CGPointZero inView:self];
- }
- @end
- 不同于UIScrollView,定制的互动视图类没有实现任何边界检查
- 使用例子:
- CATiledLayer:
- 当需要绘制很大图片时,如果读取整个图片,载入大图会很慢,即时个人能接受载入慢甚至卡主线程,但是
- 因为所有显示在屏幕上的图片最终会被转换为OpenGL纹理,该纹理有一个最大尺寸(2048*2048或4096*4096)
- 该专用图层便是解决该类问题而存在:将大图分解成小片然后将他们单独按需载入
- 使用步骤:
1.使用Mac OS命令行程序,使用CATiledLayer将一个大图裁剪成多个小图并存储到不同文件中
/*裁剪图片成小图的终端程序,*/
-
-
- #import <AppKit/AppKit.h>
- int main(int argc, const char * argv[])
- {
- @autoreleasepool{
- //handle incorrect arguments
- if (argc < 2) {
- NSLog(@"TileCutter arguments: inputfile");
- return 0;
- }
- //input file
- NSString *inputFile = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
- //tile size
- CGFloat tileSize = 256; //output path
- NSString *outputPath = [inputFile stringByDeletingPathExtension];
- //load image
- NSImage *image = [[NSImage alloc] initWithContentsOfFile:inputFile];
- NSSize size = [image size];
- NSArray *representations = [image representations];
- if ([representations count]){
- NSBitmapImageRep *representation = representations[0];
- size.width = [representation pixelsWide];
- size.height = [representation pixelsHigh];
- }
- NSRect rect = NSMakeRect(0.0, 0.0, size.width, size.height);
- CGImageRef imageRef = [image CGImageForProposedRect:&rect context:NULL hints:nil];
- //calculate rows and columns
- NSInteger rows = ceil(size.height / tileSize);
- NSInteger cols = ceil(size.width / tileSize);
- //generate tiles
- for (int y = 0; y < rows; ++y) {
- for (int x = 0; x < cols; ++x) {
- //extract tile image
- CGRect tileRect = CGRectMake(x*tileSize, y*tileSize, tileSize, tileSize);
- CGImageRef tileImage = CGImageCreateWithImageInRect(imageRef, tileRect);
- //convert to jpeg data
- NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:tileImage];
- NSData *data = [imageRep representationUsingType: NSJPEGFileType properties:nil];
- CGImageRelease(tileImage);
- //save file
- NSString *path = [outputPath stringByAppendingFormat: @"_%02i_%02i.jpg", x, y];
- [data writeToFile:path atomically:NO];
- }
- }
- }
- return 0;
- }
- /*
- 然后在终端调用
- > path/to/TileCutterApp path/to/Snowman.jpg
- */
-
2.使用CATiledLayer专用图层结合UIScrollView使用,实现-drawLayer:inContext:方法
-
-
- 当需要载入新小图时,CATiledLayer会调用该方法。
- 使用例子:
- CATiledLayer *tileLayer=[CATiledLayer layer];
- tileLayer.frame=CGRectMake(0,0,2048,2048);
- tileLayer.delegate=self;
- tileLayer.contentsScale = [UIScreen mainScreen].scale;
- [scrollView.layer addSublayer:tileLayer];
- scrollView.contentSize=tileLayer.frame.size;
- [tileLayer setNeedsDisplay];
- -(void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx{
- CGRect bounds=CGContextGetClipBoundingBox(ctx);
- NSInteger x=floor(bounds.origin.x/layer.tileSize.width*scale);
- NSInteger y=floor(bounds.origin.y/layer.tileSize.height*scale);
- 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();
- }
- /*
- 滑动时,CATiledLayer载入小图默认带淡入效果进入界面,
- 可以通过fadeDuration属性改变淡入时长或直接禁用掉;
- -drawLayer:inContext:方法可以在多个线程中同时地并发调用,需小心线程安全
- */
-
- CAEmitterLayer
- 一个高性能的粒子引擎,用来创建实时例子动画如:烟雾,火,雨等效果
- 该专用图层像是许多CAEmitterCell(定义一个粒子效果)的容器
- 一般需要为不同的粒子效果定义一个或多个CAEmitterCell作为模版
- 一个CAEmitterCell类似一个CALayer:
- 有一个contents属性可以定义一个CGImage,
- 另外有一些可设置属性控制表现与行为
- 基本属性可以分3种:
1.粒子的某一属性的初始值,如color
2.粒子某一属性的变化范围
3.指定值在时间线上的变化
-
- 而该专用图层负责基于这些模版实例化一个粒子流,并且通过属性控制整个例子系统的位置与形状
- 该专用图层的一些属性:
- birthTate
- lifetime
- celocity
- /*同样在CAEmitterCell中也有上面这三个属性,最终这些属性以相乘方式作用在一起*/
- preservesDepth:是否将3D粒子系统平面化到一个图层(默认)或者可以在3D空间中混合其它图层
- renderMode:控制着在视觉上例子图片是如何混合。
- 使用例子:
- CAEmitterLayer *emitter = [CAEmitterLayer layer];
- emitter.frame = self.containerView.bounds;
- [self.containerView.layer addSublayer:emitter];
- emitter.renderMode = kCAEmitterLayerAdditive;
- emitter.emitterPosition = CGPointMake(emitter.frame.size.width / 2.0, emitter.frame.size.height / 2.0);
- 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;
- emitter.emitterCells = @[cell];
- CAEAGLLayer
- OpenGL提供Core Animation的基础,是底层的C接口,没有对象或是图层的继承概念,直接与硬件通信
- iOS5引入GLKit,去掉了一些设置OpenGL的复杂性,提供一个叫CLKView的UIView子类,处理大部分的设置与绘制工作
- 但是仍需通过CAEAGLLayer配置各种各样的OpenGL绘图缓冲的底层配置项,CAEAGLLayer用来显示任意OpenGL图形
- 使用前需要引入GLKit与OpenGLES框架
- 以下例子,使用OpenGL ES2.0的绘图上下文,并渲染一个有色三角:
- #import "ViewController.h"
- #import <QuartzCore/QuartzCore.h>
- #import <GLKit/GLKit.h>
- @interface ViewController ()
- @property (nonatomic, weak) IBOutlet UIView *glView;
- @property (nonatomic, strong) EAGLContext *glContext;
- @property (nonatomic, strong) CAEAGLLayer *glLayer;
- @property (nonatomic, assign) GLuint framebuffer;
- @property (nonatomic, assign) GLuint colorRenderbuffer;
- @property (nonatomic, assign) GLint framebufferWidth;
- @property (nonatomic, assign) GLint framebufferHeight;
- @property (nonatomic, strong) GLKBaseEffect *effect;
- @end
- @implementation ViewController
- - (void)setUpBuffers
- {
- //set up frame buffer
- glGenFramebuffers(1, &_framebuffer);
- glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
- //set up color render buffer
- glGenRenderbuffers(1, &_colorRenderbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer);
- [self.glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:self.glLayer];
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_framebufferWidth);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_framebufferHeight);
- //check success
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- NSLog(@"Failed to make complete framebuffer object: %i", glCheckFramebufferStatus(GL_FRAMEBUFFER));
- }
- }
- - (void)tearDownBuffers
- {
- if (_framebuffer) {
- //delete framebuffer
- glDeleteFramebuffers(1, &_framebuffer);
- _framebuffer = 0;
- }
- if (_colorRenderbuffer) {
- //delete color render buffer
- glDeleteRenderbuffers(1, &_colorRenderbuffer);
- _colorRenderbuffer = 0;
- }
- }
- - (void)drawFrame {
- //bind framebuffer & set viewport
- glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
- glViewport(0, 0, _framebufferWidth, _framebufferHeight);
- //bind shader program
- [self.effect prepareToDraw];
- //clear the screen
- glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0, 0.0, 0.0, 1.0);
- //set up vertices
- GLfloat vertices[] = {
- -0.5f, -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.5f, -0.5f, -1.0f,
- };
- //set up colors
- GLfloat colors[] = {
- 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
- };
- //draw triangle
- glEnableVertexAttribArray(GLKVertexAttribPosition);
- glEnableVertexAttribArray(GLKVertexAttribColor);
- glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, vertices);
- glVertexAttribPointer(GLKVertexAttribColor,4, GL_FLOAT, GL_FALSE, 0, colors);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- //present render buffer
- glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
- [self.glContext presentRenderbuffer:GL_RENDERBUFFER];
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //set up context
- self.glContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
- [EAGLContext setCurrentContext:self.glContext];
- //set up layer
- self.glLayer = [CAEAGLLayer layer];
- self.glLayer.frame = self.glView.bounds;
- [self.glView.layer addSublayer:self.glLayer];
- self.glLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking:@NO, kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8};
- //set up base effect
- self.effect = [[GLKBaseEffect alloc] init];
- //set up buffers
- [self setUpBuffers];
- //draw frame
- [self drawFrame];
- }
- - (void)viewDidUnload
- {
- [self tearDownBuffers];
- [super viewDidUnload];
- }
- - (void)dealloc
- {
- [self tearDownBuffers];
- [EAGLContext setCurrentContext:nil];
- }
- @end
- AVPlayerLayer
- AVPlayerLayer是由AVFoundation框架提供
- 用来播放视频,是MPMoivePlayer的底层实现,提供显示视频的底层控制
- 通过调用+playerLayerWithPlayer:方法创建一个绑定了视频播放器的图层
- 或者先创建一个图层,用play属性绑定一个AVPlayer实例
- 使用例子:
- #import <AVFoundation/AVFoundation.h>
- NSURL *URL = [[NSBundle mainBundle] URLForResource:@"Ship" withExtension:@"mp4"];
- AVPlayer *player = [AVPlayer playerWithURL:URL];
- AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
- playerLayer.frame = self.containerView.bounds;
- [self.containerView.layer addSublayer:playerLayer];
- [player play];
- 因为该专用图层是CALayer的子类,也就可以对其进行3D,圆角,有色边框,蒙板,阴影等效果设置
- 使用例子:(续上使用例子)
- playerLayer.frame = self.containerView.bounds;
- [self.containerView.layer addSublayer:playerLayer];
- CATransform3D transform = CATransform3DIdentity;
- transform.m34 = -1.0 / 500.0;
- transform = CATransform3DRotate(transform, M_PI_4, 1, 1, 0);
- playerLayer.transform = transform;
- playerLayer.masksToBounds = YES;
- playerLayer.cornerRadius = 20.0;
- playerLayer.borderColor = [UIColor redColor].CGColor;
- playerLayer.borderWidth = 5.0;
- [player play];