zoukankan      html  css  js  c++  java
  • CALayer04-自定义图层

    一、UIView和CALayer的其他关系

    * UIView可以通过subviews属性访问所有的子视图,类似地,CALayer也可以通过sublayers属性访问所有的子层

    * UIView可以通过superview属性访问父视图,类似地,CALayer也可以通过superlayer属性访问父层

    如果两个UIView是父子关系,那么它们内部的CALayer也是父子关系。

    二、自定义图层方法一

    1、方法描述:创建一个CALayer的子类,然后覆盖drawInContext:方法,使用Quartz2D API进行绘图

     

    2.在.m文件中覆盖drawInContext:方法,在里面绘图

    只有明显地调用setNeedsDisplay方法,才会调用drawInContext:方法进行绘制
    -(void)drawInContext:(CGContextRef)ctx//上下文
    {
        //颜色,在这边使用UIColor是没有用的,CALayer是QuartzCore框架的,所有UI的东西是没有用的在这边
        CGContextSetRGBFillColor(ctx, 1.0, 0, 1.0, 1);
        
        //画圆
        CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 50, 50));
        
        //渲染,直接实心绘制
        CGContextFillPath(ctx);
    }

    3、viewDidLoad方法中调用

        CustomLayer *layer = [CustomLayer layer];
        layer.bounds = CGRectMake(0, 0, 100, 100);
        layer.backgroundColor = [UIColor blueColor].CGColor;
        layer.anchorPoint = CGPointZero;
        //图层和view不一样,layer不会自动的调用drawInContext:,只有明显地调用setNeedsDisplay方法,才会调用drawInContext:方法进行绘制
        [layer setNeedsDisplay];
        
        [self.view.layer addSublayer:layer];

    三、自定义view来绘制,与上面的自定义layer进行对比

    //UIView绘制图形的drawRect:
    -(void)drawRect:(CGRect)rect
    {
        //需要主动拿图层上下文,然后在上下文中绘制图片
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        //填充色
        CGContextSetRGBFillColor(ctx, 1.0, 0, 1.0, 1);
        
        //画圆
        CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 50, 50));
        
        //渲染,直接实心绘制
        CGContextFillPath(ctx);
        
        //上面所绘制的东西相当于下面这个语句,图形上下文中绘制的所有的东西传到图层中去了
        //UIView能够显示,主要是layer,这里拿到的上下文就是图层方法-(void)drawInContext:(CGContextRef)ctx中传人的上下文
    //    [self.layer drawInContext:ctx];
    }

    四、自定义图层方法二,不需要自定义,不需要继承,通过代理进行绘制

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self diyLayer2];
    }
    
    #pragma make - 创建图层方法二
    - (void)diyLayer2
    {
        CALayer *layer = [CALayer layer];
        layer.bounds = CGRectMake(0, 0, 100, 100);
        layer.backgroundColor = [UIColor blueColor].CGColor;
        layer.anchorPoint = CGPointZero;
        layer.position = CGPointMake(100, 100);
        //如果代理方法没有协议,说明任何对象都可以当它的代理,代表这个方法是NSObject对象的。进去看一下,是NSObject分类方法。
        //一个view内部自带的图层的代理,默认就是view本身,不可以修改自带layer的代理
        layer.delegate = self;
        //图层需要主动的调用绘制方法
        [layer setNeedsDisplay];
        [self.view.layer addSublayer:layer];
    }
    
    #pragma make - 图层的代理方法
    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
    {
        CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
        CGContextAddRect(ctx, CGRectMake(0, 0, 20, 20));
        CGContextFillPath(ctx);
    }
    五、通过代理方法自定义图层layer需要注意:
    view根层的layer的代理就是view本身,view内部那个图层怎么会东西由view决定,view实现drawRect:

    * 这里要注意的是:不能再将某个UIView设置为CALayer的delegate,因为UIView对象已经是它内部根层的delegate,再次设置为其他层的delegate就会出问题。UIView和它内部CALayer的默认关系图:

     总之一句话:一个view内部自带的图层不可以改它的代理

        //view根层的layer的代理就是view本身
        //例子一
        self.view.layer.delegate == self.view
        
        //例子二
        UIView *view1 = [[UIView alloc]init];
        view1.layer.delegate == view1;
        
        //例子三
        UIImageView *imageview1 = [[UIImageView alloc]init];
        imageview1.layer.delegate == imageview1
        
        //不可以将控制器作为根层layer的代理,否则什么都出不来
        imageview1.layer.delegate = self;

    六:总结

    无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。

    七:UIView的详细显示过程

     * 当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

    * 平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

  • 相关阅读:
    hdu2151
    hdu1028
    hdu1398
    hdu1465
    hdu2853
    poj2195
    poj2255
    JS正则校验数字,特殊字符,邮箱基本格式
    JS正则校验数字,特殊字符,邮箱基本格式
    io读取文件内容乱码处理
  • 原文地址:https://www.cnblogs.com/yipingios/p/4501460.html
Copyright © 2011-2022 走看看