之前讲到几个常用的CALayer的子类,对对对,就是他:iOS动画篇_CALayer这些牛逼的子类你造吗。今天我们来讲其他几个吧,要不然,我不说你是不是以为我不会!!!
那我们今天就从一个比较酷炫的开始:
CATransformLayer
我们先看一下系统有没有像之前讲过的几个子类一样,给它一些特殊的属性或者方法:
@interface CATransformLayer : CALayer @end
啥都没有,我擦嘞,但是上面好像有一段描述我们看一下:
/* "Transform" layers are used to create true 3D layer hierarchies. * * Unlike normal layers, transform layers do not project (i.e. flatten) * their sublayers into the plane at Z=0. However due to this neither * do they support many features of the 2D compositing model: * * - only their sublayers are rendered (i.e. no background, contents, * border) * * - filters, backgroundFilters, compositingFilter, mask, masksToBounds * and shadow related properties are ignored (they all assume 2D * image processing of the projected layer) * * - opacity is applied to each sublayer individually, i.e. the transform * layer does not form a compositing group. * * Also, the -hitTest: method should never be called on transform * layers (they do not have a 2D coordinate space into which to map the * supplied point.) CALayer will pass over transform layers directly to * their sublayers, applying the effects of the transform layer's * geometry when hit-testing each sublayer. */
我们从中可以看出它作为父Layer时,对他的sublayers会有3D效果,也就是说不平面化它的子图层,大家一提到3D效果,就会想到一个神奇的东西景深,先说一下景深是个什么东西,提到景深,那我们就一定要说CATransform3D,它定义了一个4x4 的 CGFloat值的矩阵,就是这样的:
struct CATransform3D { CGFloat m11, m12, m13, m14; CGFloat m21, m22, m23, m24; CGFloat m31, m32, m33, m34; CGFloat m41, m42, m43, m44; }
其中的m34,就是上面提到的景深效果的源头,我们写一段代码看一下:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CALayer *layer_ = [CALayer layer]; layer_.bounds = CGRectMake(0, 0, 100, 100); layer_.position = CGPointMake(self.view.center.x, 200); layer_.opacity = 0.6; layer_.backgroundColor = [UIColor redColor].CGColor; layer_.borderWidth = 5; layer_.borderColor = [[UIColor greenColor] colorWithAlphaComponent:0.4].CGColor; layer_.cornerRadius = 20; layer_.masksToBounds = YES; [self.view.layer addSublayer:layer_]; // CATransform3D fromValue_ = CATransform3DIdentity; fromValue_ = CATransform3DRotate(fromValue_, M_PI_2 / 2, 0, 1, 0); layer_.transform = fromValue_; CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.position = self.view.center; layer.opacity = 0.6; layer.backgroundColor = [UIColor blueColor].CGColor; layer.borderWidth = 5; layer.borderColor = [[UIColor orangeColor] colorWithAlphaComponent:0.4].CGColor; layer.cornerRadius = 20; layer.masksToBounds = YES; [self.view.layer addSublayer:layer]; // CATransform3D fromValue = CATransform3DIdentity; fromValue.m34 = 1.0 / -500; fromValue = CATransform3DRotate(fromValue, M_PI_2 / 2, 0, 1, 0); layer.transform = fromValue; }
运行结果:
是不是明显发现蓝色的layer3D效果更强烈一些。
下面我们试一下这样的代码:
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.opacity = 0.6; layer.backgroundColor = [UIColor redColor].CGColor; layer.borderWidth = 5; layer.borderColor = [[UIColor greenColor] colorWithAlphaComponent:0.4].CGColor; layer.cornerRadius = 20; layer.masksToBounds = YES; CALayer *layer_2 = [CALayer layer]; layer_2.bounds = CGRectMake(0, 0, 100, 100); layer_2.opacity = 0.6; layer_2.backgroundColor = [UIColor blueColor].CGColor; layer_2.borderWidth = 5; layer_2.borderColor = [[UIColor orangeColor] colorWithAlphaComponent:0.4].CGColor; layer_2.cornerRadius = 20; layer_2.masksToBounds = YES; // CALayer *containerLayer = [CALayer layer]; containerLayer.bounds = CGRectMake(0, 0, 100, 100); containerLayer.position = self.view.center; layer.position = CGPointMake(50, 50); layer_2.position = CGPointMake(50, 50); [containerLayer addSublayer:layer]; [containerLayer addSublayer:layer_2]; [self.view.layer addSublayer:containerLayer]; // CATransform3D containerTransform = CATransform3DIdentity; containerTransform.m34 = -1.0 / 500.0; containerLayer.transform = containerTransform; // CATransform3D fromValue = CATransform3DIdentity; fromValue = CATransform3DRotate(fromValue, M_PI_2, 0, 1, 0); fromValue = CATransform3DTranslate(fromValue, 0, 0, -10); layer.transform = fromValue; CATransform3D fromValue_2 = CATransform3DIdentity; fromValue_2 = CATransform3DRotate(fromValue_2, M_PI_2, 0, 1, 0); fromValue_2 = CATransform3DTranslate(fromValue_2, 0, 0, -50); layer_2.transform = fromValue_2; }
运行结果,一片空白,啥都没有。
我们做一处改动:
CATransformLayer *containerLayer = [CATransformLayer layer];
运行结果:
??:所以有人说CATransformLayer便是给他的子图层添加了景深的效果。瞎搞,把设置景深的代码containerTransform.m34 = -1.0 / 500.0;去掉,运行,你会发现还是一片空白。这就说明CATransformLayer并不是这么个作用。那这个东西的特殊之处究竟是什么呢?
其实就是上面说的:CATransformLayer并不平面化它的子图层,所以它能够用于构造一个层级分明的3D结构。
上代码:
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.opacity = 0.6; layer.backgroundColor = [UIColor redColor].CGColor; layer.borderWidth = 5; layer.borderColor = [[UIColor greenColor] colorWithAlphaComponent:0.4].CGColor; layer.cornerRadius = 20; layer.masksToBounds = YES; CALayer *containerLayer = [CALayer layer]; containerLayer.bounds = CGRectMake(0, 0, 100, 100); containerLayer.position = self.view.center; layer.position = CGPointMake(50, 50); layer_2.position = CGPointMake(50, 50); [containerLayer addSublayer:layer]; [self.view.layer addSublayer:containerLayer]; CATransform3D containerTransform = CATransform3DIdentity; containerLayer.transform = containerTransform; CATransform3D fromValue = CATransform3DIdentity; fromValue = CATransform3DRotate(fromValue, M_PI_2, 0, 1, 0); layer.transform = fromValue; }
运行结果:不出所料,一片空白。
于是,我们把containerLayer由CALayer改成CATransformLayer ,结果,还是一片空白。
现在,你肯定觉的我也是在扯淡,下面精彩的部分来了:
我们给containerLayer添加一个新的transform,代码也就是这样的:
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.opacity = 0.6; layer.backgroundColor = [UIColor redColor].CGColor; layer.borderWidth = 5; layer.borderColor = [[UIColor greenColor] colorWithAlphaComponent:0.4].CGColor; layer.cornerRadius = 20; layer.masksToBounds = YES; CALayer *containerLayer = [CALayer layer]; containerLayer.bounds = CGRectMake(0, 0, 100, 100); containerLayer.position = self.view.center; layer.position = CGPointMake(50, 50); layer_2.position = CGPointMake(50, 50); [containerLayer addSublayer:layer]; [self.view.layer addSublayer:containerLayer]; CATransform3D containerTransform = CATransform3DIdentity; //看这,我是新加的 containerTransform = CATransform3DRotate(containerTransform, M_PI_2, 0, 1, 0); // containerLayer.transform = containerTransform; CATransform3D fromValue = CATransform3DIdentity; fromValue = CATransform3DRotate(fromValue, M_PI_2, 0, 1, 0); layer.transform = fromValue; }
运行结果:
现在,我们再把containerLayer由CATransformLayer改成CALayer ,结果,一片空白!你是不是明白了呢?其实还是上面那句话!
我们利用它来做一个立方体:
#import "ViewController.h" @interface ViewController (){ CGPoint startPoint; CATransformLayer *s_Cube; float pix, piy; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // CATransform3D c1t = CATransform3DIdentity; CALayer *cube1 = [self cubeWithTransform:c1t]; s_Cube = (CATransformLayer *)cube1; [self.view.layer addSublayer:cube1]; } - (CALayer *)faceWithTransform:(CATransform3D)transform color:(UIColor*)color { CALayer *face = [CALayer layer]; face.frame = CGRectMake(-50, -50, 100, 100); face.backgroundColor = color.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 color:[UIColor redColor]]]; //右 ct = CATransform3DMakeTranslation(50, 0, 0); ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0); [cube addSublayer:[self faceWithTransform:ct color:[UIColor yellowColor]]]; //上 ct = CATransform3DMakeTranslation(0, -50, 0); ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0); [cube addSublayer:[self faceWithTransform:ct color:[UIColor blueColor]]]; //下 ct = CATransform3DMakeTranslation(0, 50, 0); ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0); [cube addSublayer:[self faceWithTransform:ct color:[UIColor brownColor]]]; //左 ct = CATransform3DMakeTranslation(-50, 0, 0); ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0); [cube addSublayer:[self faceWithTransform:ct color:[UIColor greenColor]]]; //后 ct = CATransform3DMakeTranslation(0, 0, -50); ct = CATransform3DRotate(ct, M_PI, 0, 1, 0); [cube addSublayer:[self faceWithTransform:ct color:[UIColor orangeColor]]]; // CGSize containerSize = self.view.bounds.size; cube.position = CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0); cube.transform = transform; return cube; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; startPoint = [touch locationInView:self.view]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint currentPosition = [touch locationInView:self.view]; CGFloat deltaX = startPoint.x - currentPosition.x; CGFloat deltaY = startPoint.y - currentPosition.y; CATransform3D c1t = CATransform3DIdentity; c1t = CATransform3DRotate(c1t, pix + M_PI_2 * deltaY / 100, 1, 0, 0); c1t = CATransform3DRotate(c1t, piy - M_PI_2 * deltaX / 100, 0, 1, 0); s_Cube.transform = c1t; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint currentPosition = [touch locationInView:self.view]; CGFloat deltaX = startPoint.x - currentPosition.x; CGFloat deltaY = startPoint.y - currentPosition.y; pix = M_PI_2 * deltaY / 100; piy = -M_PI_2 * deltaX / 100; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
运行结果:
如果针对上面的解释你还不是很理解,那么你可以把这个立方体的CATransformLayer换成CALayer,试试看喽。
CAReplicatorLayer
通过这个名字,我就确定它和图层复制有关,你信不信?
我们看一下系统提供的API:
@interface CAReplicatorLayer : CALayer @property NSInteger instanceCount; //复制图层的个数,包括加到上面的 @property BOOL preservesDepth; // 子图层是否平面化(看上面那个CATransformLayer) @property CFTimeInterval instanceDelay; // 复制层动画延迟时间 @property CATransform3D instanceTransform; //子图层的transform变换,一般用来决定复制图层的初始位置以及初始试图变换 @property(nullable) CGColorRef instanceColor; // 复制层颜色,该颜色是与本体元素色值相乘,鬼知道是什么颜色 @property float instanceRedOffset; // 复制层红色偏移量 @property float instanceGreenOffset; // 复制层绿色偏移量 @property float instanceBlueOffset; // 复制层蓝色偏移量 @property float instanceAlphaOffset; // 复制层透明度偏移量 @end
属性虽少,变化很大,主要是于核心动画的强强联合,他就有无限的可能性,三种效果,您上眼:
NO.1:深夜电台广播
-(void)lineWave{ CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.bounds = self.view.frame; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor].CGColor; layer.bounds = CGRectMake(0, 0, 10, 40); layer.position = CGPointMake(50, self.view.center.y); [replicatorLayer addSublayer:layer]; // CABasicAnimation *basicAni = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"]; basicAni.toValue = @(0.1); basicAni.duration = 0.3; basicAni.autoreverses = YES; basicAni.repeatCount = NSIntegerMax; [layer addAnimation:basicAni forKey:@"layerPosition"]; replicatorLayer.instanceCount = 8; CATransform3D transform = CATransform3DIdentity; transform = CATransform3DTranslate(transform, 40, 0, 0); replicatorLayer.instanceTransform = transform; replicatorLayer.instanceDelay = 0.3; }
运行结果:
NO. 2:催眠等待小圈圈
-(void)lineRoundRoll{ CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.bounds = self.view.frame; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor].CGColor; layer.cornerRadius = 20; layer.bounds = CGRectMake(0, 0, 40, 40); layer.position = CGPointMake(50, self.view.center.y); [replicatorLayer addSublayer:layer]; layer.transform = CATransform3DMakeScale(0.01, 0.01, 0.01); // CABasicAnimation *basicAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; basicAni.fromValue = @(1); basicAni.toValue = @(0.1); basicAni.duration = 0.75; basicAni.repeatCount = NSIntegerMax; [layer addAnimation:basicAni forKey:@"layerPosition"]; replicatorLayer.instanceCount = 15; replicatorLayer.preservesDepth = YES; CATransform3D transform = CATransform3DIdentity; transform = CATransform3DRotate(transform, M_PI * 2 / 15.0, 0, 0, 1); replicatorLayer.instanceTransform = transform; replicatorLayer.instanceDelay = 0.05; replicatorLayer.instanceAlphaOffset = -1.0 / 15.0; //replicatorLayer.instanceBlueOffset = 1.0 / 15; //replicatorLayer.instanceColor = [UIColor redColor].CGColor; }
运行结果:
NO.3:路径跟随
-(void)followPathLayer{ UIBezierPath *path = [self followPath]; // CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.bounds = self.view.frame; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor].CGColor; layer.cornerRadius = 5; layer.bounds = CGRectMake(0, 0, 10, 10); layer.position = CGPointMake(20, self.view.center.y); [replicatorLayer addSublayer:layer]; // CAKeyframeAnimation *basicAni = [CAKeyframeAnimation animationWithKeyPath:@"position"]; basicAni.path = path.CGPath; basicAni.duration = 3; basicAni.repeatCount = NSIntegerMax; [layer addAnimation:basicAni forKey:@"layerPosition"]; // replicatorLayer.instanceCount = 15; replicatorLayer.instanceDelay = 0.3; } -(UIBezierPath*)followPath{ //CAShapeLayer *shapeLayer = [CAShapeLayer layer]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(20, self.view.center.y)]; [path addCurveToPoint:CGPointMake(self.view.bounds.size.width - 20, self.view.center.y) controlPoint1:CGPointMake(130, self.view.center.y - 100) controlPoint2:CGPointMake(240, self.view.center.y + 100)]; [path closePath]; //shapeLayer.path = path.CGPath; //shapeLayer.lineWidth = 5; //shapeLayer.strokeColor = [UIColor grayColor].CGColor; //shapeLayer.fillColor = [UIColor clearColor].CGColor; //[self.view.layer addSublayer:shapeLayer]; return path; }
运行结果:
这几个效果只是提供几个思路,抛砖引玉啦。(这鬼录屏卡帧加模糊,大家将就着看。)
CAScrollLayer
一看到这个你一定想到了UIScrollView,其实它们并没有什么卵关系,并且我个人觉得这个东西好像没有太大的用处。首先,他没有提供有关边界的相关思路,另外,也不能响应交互。只有一下滚到这,滚到那的方法。
同样我们可以看到在这个文件下,还有个CALayer的CALayerScrolling的分类,不要以为它给CALayer添加了可滑动的方法,其实只是查找第一个可用的CAScrollLayer,并将制定点或者指定区域滚动到可视范围。
不过为了看一下它的效果,使它响应时间,我们可以用UIView的子类来自己写一个简单的ScrollView:
// // YSScrollView.m // CAScrollLayerDemo // // Created by ys on 2017/3/13. // Copyright ? 2017年 ys. All rights reserved. // #import "YSScrollView.h" @implementation YSScrollView + (Class)layerClass { return [CAScrollLayer class]; } - (void)setUp { self.layer.masksToBounds = YES; // UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)]; [self addGestureRecognizer:panGes]; } - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self setUp]; } return self; } - (void)panAction:(UIPanGestureRecognizer *)pan { CGPoint offset = self.bounds.origin; offset.x -= [pan translationInView:self].x; offset.y -= [pan translationInView:self].y; // [(CAScrollLayer *)self.layer scrollToPoint:offset]; // [pan setTranslation:CGPointZero inView:self]; } @end 然后调用加载一张大图: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. YSScrollView *ysSView = [[YSScrollView alloc] initWithFrame:self.view.bounds]; UIImageView* imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 700, 1040)]; imageView.image = [UIImage imageNamed:@"0101010.jpg"]; [self.view addSubview:ysSView]; [ysSView addSubview:imageView]; }
运行结果:
我们发现,其实他并没有滑动区域的限制,本人才疏学浅,望高人指点什么时候用这个东西。
CATiledLayer
一个大神必备的Layer子类,为节省内存渲染开销提供了途径。比如我们要去加载一个世界地图,精确到你们村的那种,如果全部一次性加载到内存中,这无疑是吃不消的,所以我们可以把地图一片片切开,然后按部分加载,大家联想一下地图应用,应该就知道大致是什么效果。我们直接上代码:
#import "ViewController.h" @interface ViewController () @property (nonatomic, strong) UIScrollView *scrollView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // CATiledLayer *tileLayer = [CATiledLayer layer]; tileLayer.frame = CGRectMake(0, 0, self.view.frame.size.width * 4, self.view.frame.size.height * 4); tileLayer.tileSize = self.view.frame.size; tileLayer.delegate = self; // self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:_scrollView]; self.scrollView.contentSize = tileLayer.frame.size; [self.scrollView.layer addSublayer:tileLayer]; // [tileLayer setNeedsDisplay]; } -(void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx{ CGRect bounds = CGContextGetClipBoundingBox(ctx); NSInteger x = floor(bounds.origin.x / layer.tileSize.width); NSInteger y = floor(bounds.origin.y / layer.tileSize.height); // NSString *imageName = [NSString stringWithFormat: @"image_%@_%@", @(x), @(y)]; NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"jpg"]; UIImage *tileImage = [UIImage imageWithContentsOfFile:imagePath]; // UIGraphicsPushContext(ctx); [tileImage drawInRect:bounds]; UIGraphicsPopContext(); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }
@end
运行结果:
其实新加载的图像碎片都是淡入到界面的(万恶的录屏软件,根本看不出来)。这是系统自己带的默认效果,你可以通过调节fadeDuration属性来修改改淡入动画的时长。
CATextLayer
我们还是从系统提供的API入手:
@property(nullable, copy) id string; //显示内容 @property(nullable) CFTypeRef font; //字体 @property CGFloat fontSize; //字号 @property(nullable) CGColorRef foregroundColor; //文字颜色 @property(getter=isWrapped) BOOL wrapped;//是否自适应layer的bounds的大小 @property(copy) NSString *truncationMode;//文字省略方式,其实就是显示不下时省略号的位置 @property(copy) NSString *alignmentMode;// 对齐方式
我们来用它显示一段文字,你可以自由修改一下它的属性来熟悉每个属性的作用:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // CATextLayer *textLayer = [CATextLayer layer]; textLayer.bounds = CGRectMake(0, 0, 200, 200); textLayer.position = self.view.center; [self.view.layer addSublayer:textLayer]; textLayer.foregroundColor = [UIColor blackColor].CGColor; textLayer.alignmentMode = kCAAlignmentLeft; textLayer.wrapped = YES; //以Retina方式来渲染,防止画出来的文本模糊 textLayer.contentsScale = [UIScreen mainScreen].scale; textLayer.truncationMode = kCATruncationEnd; 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 = @"Age has reached the end of the beginning of a word. May be guilty in his seems to passing a lot of different life became the appearance of the same day; May be back in the past, to oneself the paranoid weird belief disillusionment, these days, my mind has been very messy, in my mind constantly. Always feel oneself should go to do something, or write something. Twenty years of life trajectory deeply shallow, suddenly feel something, do it."; textLayer.string = text; }
运行结果:
CAEAGLLayer,AVPlayerLayer
CAEAGLLayer看起来就很高大上,其实真的挺高大上的,没有OpenGL知识基础的很难理解更不用说使用了,哪天,等我学会freeStyle,我唱给你听,呦,呦。(你写代码有freeStyle吗?)
AVPlayerLayer它属于AVFoundation框架,不用怀疑,它就是用来播放视频的,+ (AVPlayerLayer *)playerLayerWithPlayer:(nullable AVPlayer *)player;它的初始化依赖于AVPlayer,当然,它既然是CALayer的子类,我们就可以对它进行酷炫的效果变换,同样也克服了系统提供的播放器由于高度的封装性, 使得自定义播放器变的很难的问题。改天,你有需求,我有时间,不如我们写一个播放器啊。
总结
CALayer的所有子类都说完了,希望在一定的程度上能给你的开发带来方便,仅此而已,我们下期再见。
刚才说到的播放器的需求大概应该必需就是这样的!
上一篇传送门:iOS动画篇_CALayer这些牛逼的子类你造吗
作者:CornBallast
链接:http://www.jianshu.com/p/b3e5444c9746
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。