<pre name="code" class="html">自定义图层 和 顺序
- (void)viewDidLoad {
[super viewDidLoad];
MyView *muView = [[MyView alloc] initWithFrame:self.view.bounds];
muView.backgroundColor = [UIColor redColor];
// muView.layer.delegate = muView;
// [muView setNeedsDisplay];
[self.view addSubview:muView];
// [self diyLayer2];
//
// // 视图图层的代理 是 视图本身 不能修改代理
// self.view.layer.delegate = self.view;
// 0. 无论采取哪种方式,必须调用CALayer的setNeedDisplay才能正常显示图层
// 1. 当UIView需要显示时,它内部的layer层会准备好一个CGContextRef图形上下文
// 2. 调用delegate(UIView)的drawLayer:inContext方法,并且传入一个已经准备好的CGContextRef对象,
// 而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法
// 3. 平常在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入CGContextRef中,然后被拷贝至屏幕
// 1. layer 会准备一个layer Graphics context 图形上下文
// 2. 调用layer的代理方法画东西
// 3. drawlayer:incontext会调用drawrect方法 drawrect会获取layer的图形上下文
}
- (void)diyLayer2 { // 代理画
CALayer *layer = [CALayer layer];
layer.bounds = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor blueColor].CGColor;
[layer setAnchorPoint:CGPointZero];
// 设置代理
layer.position = CGPointMake(30, 40);
layer.delegate = self;
[layer setNeedsDisplay];
[self.view.layer addSublayer:layer];
}
#pragma mark - 图层 - 代理方法
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
CGContextAddRect(ctx, CGRectMake(0, 0, 30, 30));
CGContextFillPath(ctx);
}
- (void)diyLayer { // 自己画
MyLayer *layer = [MyLayer layer];
layer.bounds = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor blueColor].CGColor;
[layer setAnchorPoint:CGPointZero];
[layer setNeedsDisplay];
[self.view.layer addSublayer:layer];
}
#pragma mark - UIImageView的layer
- (void)myImageVieLayer {
UIImage *image = [UIImage imageNamed:@"icon.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageView setFrame:CGRectMake(50, 50, 200, 200)];
[self.view addSubview:imageView];
// 1. 圆角半径
// 提示:在imageView中,图层不只有一个,如果想要实现圆角效果,需要设置一个跟随属性
// masksToBounds属性可以让imageView中的所有子图层跟随imageView一起变化
imageView.layer.cornerRadius = 100.0f;
// 跟随属性
[imageView.layer setMasksToBounds:YES];
// 2. 阴影
// 提示:如果设置了makesToBounds属性,imageView的阴影效果无效
[imageView.layer setShadowColor:[UIColor redColor].CGColor];
[imageView.layer setShadowOffset:CGSizeMake(10, 10)];
[imageView.layer setShadowOpacity:1.0f];
// 3. 边框
[imageView.layer setBorderColor:[UIColor blueColor].CGColor];
[imageView.layer setBorderWidth:3.0f];
// 4. 形变属性,在CALayer的属性是3D的,不再是2D的
// 提示: 形变参数使用set方法时,只能应用一种形变(后面覆盖前面的。)
// 1> 平移属性
[imageView.layer setTransform:CATransform3DMakeTranslation(0, -100, 0)];// 向上移动100个点
// 2> 缩放属性
[imageView.layer setTransform:CATransform3DMakeScale(0.5, 1.0, 1.0)];
// 3> 旋转属性
// 要延哪个轴旋转,指定一个数值1.0即可,图像本身没有厚度,如果按照x或者y旋转90度,图像是不可见的。
[imageView.layer setTransform:CATransform3DMakeRotation(M_PI/3, 1, 0, 0)];
// 5. 利用keyPath设置形变属性 这几个属性可以组合用 和 4直接设置形变属性 不相同
// 1> 平移属性
[imageView.layer setValue:@-100 forKey:@"transform.translation.y"];
// 2> 缩放属性
[imageView.layer setValue:@0.5 forKey:@"transform.scale"];
// 3> 旋转属性
[imageView.layer setValue:@(M_PI_2) forKey:@"transform.rotation.z"];
}
#pragma mark - ‘自定义view的layer’
- (void)myViewLayer {
// 在实现核心动画时,本质上是将CALayer中的内容转化为位图,从而便于图形图形的操纵
// 每个UIView内部都有一个Layer属性
self.view.backgroundColor = [UIColor lightGrayColor];
// 1. 自定义UIView的图层属性
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
// 1) 圆角半径
myView.layer.cornerRadius = 10.0f;
// 2) 阴影
// 因为CoreAnimation是跨平台的,基于QuartzCore框架,在CoreAnimation中不能使用任何跟UI有关的方法,是因为UIKit框架仅能适用于iOS平台
// 要设置阴影除了颜色之外,还需要指定‘偏移量’和‘透明度’
// 1>阴影颜色
[myView.layer setShadowColor:[UIColor greenColor].CGColor];
// 2>阴影偏移量 左 下
[myView.layer setShadowOffset:CGSizeMake(10, 10)];
// 3> 阴影透明度
[myView.layer setShadowOpacity:1.0f];
// 3) 边框
[myView.layer setBorderWidth:3.0f];
[myView.layer setBorderColor:[UIColor blueColor].CGColor];
}
创建 自定义图层 - 锚点的使用
// 把内容画到自己的层上,当试视图在层上完成绘图后,系统会将图层拷贝到屏幕
// 每个视图都有一个层,而每个图层又有很多层
// layer的设计目的是提供视图的基本可视内容
// 1. 自定义图层
CALayer *myLayer = [CALayer layer];
// 将自定义图层添加到视图的根图层之上
[self.view.layer addSublayer:myLayer];
self.myLayer = myLayer;
// 2. 设置属性
// 1> 设置边框
[myLayer setBounds:CGRectMake(10, 10, 200, 200)];
// 2> 设置背景颜色
[myLayer setBackgroundColor:[UIColor redColor].CGColor];
// 3> 设置中心点 (默认是0,0,对应着UIView的center) position相对于父图层的位置
[myLayer setPosition:CGPointMake(10, 10)];
// 4> 设置内容
UIImage *image = [UIImage imageNamed:@"21.jpg"];
[myLayer setContents:(id)image.CGImage];
// 5> 锚点 它传说中也叫做定位点 (x,y的范围都是0-1) 决定了position的含义
// 默认值 (0.5,0.5)
// 作用:主要控制图层的位置 以及旋转的轴
//~~~~ 通过比例,锚点不需要知道图层具体的大小啊,让锚点去找position吧~~~
[myLayer setAnchorPoint:CGPointMake(1, 1)];
//
// [myLayer setTransform:CATransform3DMakeRotation(M_PI, 0, 0, 1)];
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.myLayer.anchorPoint.x == 0) {
self.myLayer.anchorPoint = CGPointMake(1, 1);
} else {
self.myLayer.anchorPoint = CGPointMake(0, 0);
}
}
隐式动画的属性 和 使用
- (void)viewDidLoad {
[super viewDidLoad];
// 1. 实例化自定义图层
CALayer *myLayer = [CALayer layer];
// 这是bounds
[myLayer setBounds:CGRectMake(0, 0, 100, 100)];
// 这是背景颜色
[myLayer setBackgroundColor:[UIColor redColor].CGColor];
// 这是中心位置
[myLayer setPosition:CGPointMake(50, 50)];
[self.view.layer addSublayer:myLayer];
self.myLayer = myLayer;
self.myLayer.hidden = YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.myLayer.hidden = NO;
UITouch *touch = touches.anyObject;
CGPoint location = [touch locationInView:self.view];
// // 关闭动画 默认0.25秒
// [CATransaction begin];
// [CATransaction setDisableActions:YES];
// 位置
[self.myLayer setPosition:location];
// 颜色
CGFloat r = arc4random_uniform(256) / 255.0;
CGFloat g = arc4random_uniform(256) / 255.0;
CGFloat b = arc4random_uniform(256) / 255.0;
UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:1.0f];
// 随机颜色
self.myLayer.backgroundColor = color.CGColor;
// 随机透明度
CGFloat alpha = (arc4random_uniform(5)+1.0)/10.0 + 0.5;
// Opacity 不透明
[self.myLayer setOpacity:alpha];
// 尺寸
NSInteger size = arc4random_uniform(50) + 51;
[self.myLayer setBounds:CGRectMake(20,20, size, size)];
// 圆角
NSInteger radius = arc4random_uniform(50);
[self.myLayer setCornerRadius:radius];
// 旋转角度
CGFloat angle = arc4random_uniform(180) / 180.0*M_PI;
[self.myLayer setTransform:CATransform3DMakeRotation(angle, 0, 0, 1)];
// 内容
// self.myLayer setContents:<#(id)#>
// [CATransaction commit];
}
CALayer 图层通过代理
- (void)viewDidLoad {
[super viewDidLoad];
// 1. 实例化子图层
CALayer *myLayer = [CALayer layer];
[myLayer setBounds:CGRectMake(0, 0, 200, 200)];
[myLayer setBackgroundColor:[UIColor redColor].CGColor];
[myLayer setCornerRadius:2.0f];
[myLayer setPosition:CGPointMake(100, 100)];
[self.view.layer addSublayer:myLayer];
self.myLayer = myLayer;
// 提示,如果要重绘CALayer,必须要调用setNeedDisplay
// 不能够将视图设置为layer的代理
[self.myLayer setDelegate:self];
[self.myLayer setNeedsDisplay];
NSLog(@"%@",self.myLayer);
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
NSLog(@"%@",layer);
// 在core animation中不能使用UI的方法
// 蓝色矩形矩形
// [[UIColor blueColor] set];
CGRect rect = CGRectMake(50, 50, 100, 100);
CGContextSetRGBFillColor(ctx, 0, 0, 1.0, 1.0);
CGContextSetRGBStrokeColor(ctx, 0, 1, 0, 1);
CGContextAddRect(ctx, rect);
CGContextDrawPath(ctx, kCGPathEOFillStroke);
// UIRectFill(rect);
}
自定义Layer
- (void)drawInContext:(CGContextRef)ctx {
NSLog(@"drawInContect");
// 绘图层Ellipse 圆形
// 青色的圆
CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100));
CGContextSetRGBFillColor(ctx, 0, 1.0, 1.0, 1.0);
CGContextDrawPath(ctx, kCGPathFill);
// CGContextFillPath(ctx);
// 蓝色的圆
CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 100, 100));
CGContextSetRGBFillColor(ctx, 0, 0, 1.0, 1.0);
CGContextDrawPath(ctx, kCGPathFill);
// 绘制头像
// 在绘图的时候可以利用上下文的形变来画图
// 可以利用形变属性的缩放实现图片的反转 (1,-1)
// 利用平移恢复位置(向下平移坐标系)
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextTranslateCTM(ctx, 0, -self.bounds.size.height);
UIImage *image = [UIImage imageNamed:@"icon.jpg"];
CGContextDrawImage(ctx, CGRectMake(50, 50, 100, 100), image.CGImage);
}
跟上一个衔接。
@interface MyView ()
@property (nonatomic,weak) MyLayer *myLayer;
@end
@implementation MyView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSLog(@"init view");
MyLayer *myLayer = [MyLayer layer];
[self.layer addSublayer:myLayer];
[myLayer setBackgroundColor:[UIColor redColor].CGColor];
[myLayer setBounds:self.bounds];
[myLayer setPosition:CGPointMake(100, 100)];
self.myLayer = myLayer;
[self.myLayer setNeedsDisplay];
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSLog(@"drawRect");
}
/** 会先调用这个方法,然后调用drawrect方法 */
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
[super drawLayer:layer inContext:ctx];
NSLog(@"draw layer");
}