码迷,mamicode.com
首页 > 其他好文 > 详细

010-CALayer(图层)

时间:2014-08-22 22:28:29      阅读:419      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   使用   io   for   数据   

问题一:什么是CALayer(图层)?

简而言之:使UIView可以显示在屏幕上的功能属性,UIView之所以可以显示在屏幕上完全是因为UIView内部含有一个CALayer属性

•在iOS中,能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView
 
•UIView本身不具备显示的功能,之所以能显示完全是因为它内部的图层属性(具有显示功能)
 
•在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层
@property(nonatomic,readonly,retain) CALayer *layer;
 
•当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,将所有内容绘制在自己的图层上,绘图完毕后,系统将图层映射到屏幕上,于是就完成了UIView的显示
// view的完整显示过程
// 1. view.layer准备了一个Layer Graphics Context(图层类型的上下文)
// 2. 调用view.layer.delegate(view)的drawLayer:inContext:,并传入刚才准备好的上下文
// 3. view的drawLayer:inContext:方法内部又会调用view的drawRect:方法
// 4. view就可以在drawRect:方法中实现绘图代码, 所有东西最终都绘制到view.layer上面
// 5. 系统再将view.layer的内容拷贝到屏幕, 于是完成了view的显示

问题二:CALayer具有哪些属性?

九大属性:

•1.内容(比如设置为图片CGImageRef)

@property(retain) id contents;
•2.位置(默认指中点,具体由anchorPoint决定)
@property CGPoint position; // 用来设置CALayer在父层中的位置 以父层的左上角为原点(0, 0)
•3.宽度和高度
@property CGRect bounds;
•4.锚点(x,y的范围都是0-1),决定了自身视图在position的坐落点
@property CGPoint anchorPoint; // 称为“定位点”、“锚点” 决定着CALayer身上的哪个点会在position属性所指的位置 以自己的左上角为原点(0, 0) 它的x、y取值范围都是0~1,默认值为(0.5, 0.5)
•5.背景颜色(CGColorRef类型)
@property CGColorRef backgroundColor;
•6.形变属性
@property CATransform3D transform;
•7.边框颜色(CGColorRef类型)
@property CGColorRef borderColor;
•8.边框宽度
@property CGFloat borderWidth;
•9.圆角半径
@property CGColorRef borderColor;

问题三:CALayer可以用来做什么呢?

•通过操作CALayer对象,可以很方便地调整UIView的一些外观属性,比如:
Ø阴影
Ø圆角大小
Ø边框宽度和颜色
Ø… …
Ø代码示例:显示效果:bubuko.com,布布扣
- (void)testView
{
    // 边框宽度
    self.purpleView.layer.borderWidth = 10;
    //    // 边框颜色
    self.purpleView.layer.borderColor = [UIColor blueColor].CGColor;
    // 圆角
    self.purpleView.layer.cornerRadius = 10;
    //    self.purpleView.layer.masksToBounds = YES; // 超出主层边框范围的内容都剪掉
    // 阴影颜色
    self.purpleView.layer.shadowColor = [UIColor blueColor].CGColor;
    // 阴影偏差
    self.purpleView.layer.shadowOffset = CGSizeMake(10, 10);
    // 阴影不透明度
    self.purpleView.layer.shadowOpacity = 0.5;
}
•还可以给图层添加动画,来实现一些比较炫酷的效果(见问题六)
ps:新建图层
bubuko.com,布布扣
- (void)viewDidLoad
{
    [super viewDidLoad];

    // 新建图层
//    CALayer *layer = [[CALayer alloc] init];
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.position = CGPointMake(200, 200);
    layer.anchorPoint = CGPointMake(1, 1);
    layer.cornerRadius = 10;
    layer.masksToBounds = YES;
    layer.contents = (id)[UIImage imageNamed:@"lufy"].CGImage;
    [self.view.layer addSublayer:layer];
    // 新建图层
    //    CALayer *layer1 = [[CALayer alloc] init];
    CALayer *layer1 = [CALayer layer];
    layer1.backgroundColor = [UIColor redColor].CGColor;
    layer1.bounds = CGRectMake(0, 0, 100, 100);
    layer1.position = CGPointMake(200, 200);
    layer1.anchorPoint = CGPointMake(0, 0);
    layer1.cornerRadius = 10;
    layer1.masksToBounds = YES;
    layer1.contents = (id)[UIImage imageNamed:@"lufy"].CGImage;
    [self.view.layer addSublayer:layer1];
}
新建图层

ps:自定义图层

bubuko.com,布布扣
@implementation WHBLayer
/**
 *  只有明显地调用setNeedsDisplay方法,才会调用drawInContext:方法进行绘制
 */
- (void)drawInContext:(CGContextRef)ctx
{
    // 红色
    CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
    // 添加圆
    CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 50, 50));
    // 实心绘制
    CGContextFillPath(ctx);
}
WHBLayer.m
bubuko.com,布布扣
- (void)viewDidLoad
{
    [super viewDidLoad];
    WHBLayer *layer = [WHBLayer layer];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor greenColor].CGColor;
    layer.anchorPoint = CGPointZero;
    [layer setNeedsDisplay]; // 绘图 会自动调用WHBLayer的drawInContext:(CGContextRef)ctf 方法
    [self.view.layer addSublayer:layer];
}
ViewController.m

问题四:为什么在CALayer中我们使用CGImageRef、CGColorRef两种数据类型来对其设置,而不用UIColor、UIImage???

原因主要:考虑移植性,跨平台性

•QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在iOS和Mac OS X上都能使用 
  ØCALayer是定义在QuartzCore框架中的
  ØCGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的
•但是UIKit只能在iOS中使用
  ØUIColor、UIImage是定义在UIKit框架中的
•为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef

 问题五:既然UIView和CALayer均可在屏幕上显示图像,那又如何在二者之间做选择?

•通过CALayer,就能做出跟UIImageView一样的界面效果
•既然CALayer和UIView都能实现相同的显示效果,那究竟该选择谁好呢?
Ø对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以
Ø如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以
Ø当然,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级

问题六:如何利用CALayer来产生一些动画效果?什么是隐式动画?

•所有手动创建的CALayer对象,都存在着隐式动画
•什么是隐式动画?
Ø当对非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果,称这些属性为Animatable Properties(可动画属性)
•列举几个常见的Animatable Properties:
// bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画
// backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画
// position:用于设置CALayer的位置。修改这个属性会产生平移动画
•可以通过动画事务(CATransaction)关闭默认的隐式动画效果
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];

 代码示例:

bubuko.com,布布扣
- (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.backgroundColor = [UIColor redColor].CGColor;
    layer.position = CGPointZero;
    layer.anchorPoint = CGPointZero;
    [self.view.layer addSublayer:layer];
    self.layer = layer;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.layer.backgroundColor = [UIColor blueColor].CGColor;
//    [CATransaction begin]; // 开启事务
//    [CATransaction setDisableActions:YES];
    
    self.layer.position = CGPointMake(100, 100);
    self.layer.opacity = 0.1;
    
//    [CATransaction commit]; // 提交事务
}
隐式动画

 

 
 

010-CALayer(图层)

标签:style   blog   http   color   os   使用   io   for   数据   

原文地址:http://www.cnblogs.com/lszwhb/p/3928050.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!