• drawLayer和drawRect


    // 这是2个方法的理解:
    1.drawLayer是一个图层的代理方法。每个UIView都由自己的基层CaLayer,它会自动调用这个drawlayer方法将其事先设置好的各种属性绘制在这个基本的图层上面
    2.如果复写这个方法,一定要调用[super drawLayer:layer inContext:ctx],否则就没意义了。
    3.这个方法里面会自动调用drawRect方法,这就是方便开发者,在基本图层的基础上再次自定义。(这就是为什么结果会先输出drawRect)
    4.破解这限制很简单:将这个代理里面做一个逻辑判断(没尝试过),再有就是写一个代理类嘛.(尼玛,千万别尝试第一种,刚直接重启了)
    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{ [super drawLayer:layer inContext:ctx]; CGContextAddEllipseInRect(ctx, CGRectMake(0,0,100,100)); CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor); CGContextFillPath(ctx); NSLog(@"drawLayer"); } -(void)drawRect:(CGRect)rect{ NSLog(@"drawRect"); }

    输出结果:

    2014-11-25 10:15:36.723 TestCoreGraphics[1282:60b] drawRect

    2014-11-25 10:15:36.725 TestCoreGraphics[1282:60b] drawLayer

     

    #pragma mark这个方法是calayer的代理方法,这个是代理调用的方法,通过复写,可以在里面绘制其不同的效果(这个方法最好不用啦,因为用代理的时候在controller里push没问题,pop就会出错,暂时没找到解决方案,以后就直接用下面的方法,通过重写layar吧)
    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
        CGContextAddEllipseInRect(ctx, CGRectMake(50, 50, 100, 100));
        
        CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
        
        CGContextFillPath(ctx);
    
    
    }
    #pragma mark这个方法是calayer自身的方法,通过复写,可以在里面绘制其不同的效果
    -(void)drawInContext:(CGContextRef)ctx{
    
       
    }
    
    #pragma mark还有一个drawRect方法是uiview的,我的理解就是uiview对就是将自身作为一个代理调用drawLayer方法,里面再调用drawrect方法
    -(void)drawRect:(CGRect)rect{
        
    }

    图层绘制举例:

    #import <UIKit/UIKit.h>
    #import "MainCaLayer.h"
    #import "MyLayerDelegate.h"
    
    @interface MainView : UIView
    
    @property(nonatomic,strong)CALayer *Mylayer;
    @property(nonatomic,strong) MyLayerDelegate *dele;
    
    @end
    #import "MainView.h"
    
    @implementation MainView
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor=[UIColor brownColor];
            self.Mylayer=[CALayer layer];
            self.Mylayer.frame=self.bounds;
            [self.layer addSublayer:self.Mylayer];
            self.Mylayer.backgroundColor=[UIColor colorWithRed:154/255.0 green:10/255.0 blue:14/255.0 alpha:0.5].CGColor;
            self.dele=[[MyLayerDelegate alloc]init];//为什么要自己保留一次再给layer的代理呢,因为layer的代理是assin模式,必须自己强引用(strong)一次再给代理,否则会报错,因为出括号当前对象就被释放了,但是用viewcontroler就不存在,因为controler的生命周期绝对比自身的view生命长久。所以稍微注意下就ok
            self.Mylayer.delegate=self.dele;
            [self.Mylayer setNeedsDisplay];//就算是第一次调用,也需要调用此方法才会被重新绘制
            
        }
        return self;
    }
    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{//其实这个方法如果不是代理类的话,是没必要复写的,因为直接调用drawRect方法就可以再基层layer上面绘制东西了,......这里这个ctx实际上就是当前上下文环境,UIkit绘制,必须再此环境中绘制,当向用UIkit绘制的时候必须调用UIGraphicsPushContext(ctx),后面还要调用UIGraphicsPopContext();在这2代码直接用uikit绘制,当然用core graphics绘制就不存在这个问题了,不需要压栈,因为这个是指定了上下文环境的,,然而uikit(默认)就需要到栈顶去取来用。eg:
                UIGraphicsPushContext(ctx);
                UIBezierPath *bepath=[[UIBezierPath alloc]init];
                [bepath addArcWithCenter:CGPointMake(100, 100) radius:90 startAngle:0 endAngle:3.14*2 clockwise:1];
                [[UIColor yellowColor] setStroke];
                [bepath stroke];
                UIGraphicsPopContext();//这个是中间插入来解释红色那段字的
    
    
    
    
    
    if (layer==[self layer]) {
            [super drawLayer:layer inContext:ctx];
            CGContextAddEllipseInRect(ctx, CGRectMake(0,0,100,100));
            CGContextSetFillColorWithColor(ctx, [UIColor yellowColor].CGColor);
            CGContextFillPath(ctx);
            NSLog(@"drawLayer");
        }
    }
    -(void)drawRect:(CGRect)rect{
    NSLog(@"drawRect");
    }
    @end

    //代理类

    #import <Foundation/Foundation.h>
    
    @interface MyLayerDelegate : NSObject
    
    @end
    #import "MyLayerDelegate.h"
    
    @implementation MyLayerDelegate
    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
            CGContextAddEllipseInRect(ctx, CGRectMake(100,200,100,100));
            CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
            CGContextFillPath(ctx);
            NSLog(@"drawLayer:inmylayer,dddd");
    }
    @end

    viewcontroler也可以用自己作为代理类(简单就不举例了)

  • 相关阅读:
    Vue 从入门到进阶之路(十)
    Vue 从入门到进阶之路(九)
    MySQL 小记
    Vue 从入门到进阶之路(八)
    Vue 从入门到进阶之路(七)
    Vue 从入门到进阶之路(六)
    Vue 从入门到进阶之路(五)
    MongoDB 小记
    Vue 从入门到进阶之路(四)
    Vue 从入门到进阶之路(三)
  • 原文地址:https://www.cnblogs.com/liyang31tg/p/4120349.html
Copyright © 2020-2023  润新知