美文网首页
drawRect:自定义view的绘图

drawRect:自定义view的绘图

作者: Areyouhere | 来源:发表于2017-01-11 10:10 被阅读0次

    绘图的步骤:1.获取上下文 2.创建路径(描述路径)3.把路径添加到上下文4.渲染上下文
    为什么要在drawRect里绘图,只有在这个方法里面才能获取到跟View的layer相关的图形上下文
    什么时候调用:当这个view要现实的时候才会调用drawRect绘制图形,一般在viewWillAppear之后(调用一次跟viewDidLoad一样加载的时候调用一次,自己可以实现调用)
    1.自己创建路径的方法

    - (void)drawRect:(CGRect)rect
    {
        //1.获取图形上下文
        CGContextRef context=UIGraphicsGetCurrentContext();
        //2.描述路径
        //创建路径
        CGMutablePathRef path=CGPathCreateMutable();
        //设置起点 path:给哪个路径设置起点
        CGPathMoveToPoint(path, NULL, 50, 50);
        //添加一根线到某个点
        CGPathAddLineToPoint(path, NULL, 100, 100);
        //3.把路径添加到上下文
        CGContextAddPath(context, path);
        //4.渲染上下文
        CGContextStrokePath(context);
    }
    

    2.用系统的默认路径绘图

    - (void)drawRect:(CGRect)rect
    {
        //获取图形上下文
        CGContextRef context=UIGraphicsGetCurrentContext();
        //描述路径
        CGContextMoveToPoint(context, 50, 50);
        CGContextAddLineToPoint(context, 100, 100);
        //默认下一根线的起点就是上一根线的终点
        CGContextAddLineToPoint(context, 120, 100);
        //多根线 但是是一个路径不能分别设置颜色(可以用自创建路径或UIBezierPath)
        CGContextMoveToPoint(context, 50, 50);
        CGContextAddLineToPoint(context, 100, 100);
        
        
        //绘制曲线
        CGContextMoveToPoint(context, 80, 50);
        
        //cpx cpy :控制点的x,y
        //    CGContextAddQuadCurveToPoint(<#CGContextRef  _Nullable c#>, <#CGFloat cpx#>, CGFloat cpy, <#CGFloat x#>, <#CGFloat y#>)
        CGContextAddQuadCurveToPoint(context, 150, 20, 120, 100);
        
        
        
        
        //设置绘图状态,一定要在渲染之前
        //颜色
        [[UIColor greenColor] setStroke];
        //线宽
        CGContextSetLineWidth(context, 10);
        //设置连接样式
        CGContextSetLineJoin(context, kCGLineJoinBevel);
        //设置顶角样式
        CGContextSetLineCap(context, kCGLineCapRound);
        //渲染上下文
        CGContextStrokePath(context);
    }
    
    

    3.用UIBezierPath 绘图

    - (void)drawRect:(CGRect)rect
    {
        //UIKit 已经封装了一些绘图的功能
        //贝塞尔路径
        //创建路径
        UIBezierPath*path=[UIBezierPath bezierPath];
        //设置起点
        [path moveToPoint:CGPointMake(50, 50)];
        //添加一根线到某个点
        [path addLineToPoint:CGPointMake(100, 100)];
        
        path.lineWidth=10;
        [[UIColor greenColor]set];
        path.lineCapStyle=kCGLineCapRound;
        path.lineJoinStyle=kCGLineJoinBevel;
        //绘制路径
        [path stroke];
        
        //创建路径
        UIBezierPath*path1=[UIBezierPath bezierPath];
        //设置起点
        [path1 moveToPoint:CGPointMake(80, 50)];
        //添加一根线到某个点
        [path1 addLineToPoint:CGPointMake(130, 100)];
        
        path1.lineWidth=10;
        [[UIColor blueColor]set];
        path1.lineCapStyle=kCGLineCapRound;
        path1.lineJoinStyle=kCGLineJoinBevel;
        //绘制路径
        [path1 stroke];
        
        //圆弧
        //Center:圆心
        //startAngle:开始弧度
        //clockwise:YES:顺时针 NO:逆时针
        UIBezierPath *path3=[UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
        //添加一根线到圆心
        [path3 addLineToPoint:CGPointMake(100, 100)];
        //封闭路径,从路径的终点到起点
        //    [path3 closePath];
        //    [path3 stroke];
        
        //填充:必须是一个完整的封闭路径,默认就会自动关闭路径
        [path3 fill];
    
    }
    

    自己实现圆形进度条

    #import <UIKit/UIKit.h>
    
    @interface DrawView : UIView
    @property(nonatomic,assign)CGFloat progress;
    @end
    
    -(void)setProgress:(CGFloat)progress
    {
        _progress=progress;
        //重绘 ,系统会先创建与view相关的上下文,然后再调用
        [self setNeedsDisplay];
    }
    
    //注意:drawRect不能手动调用,因为图形上下文我们自己创建不了,只能由系统帮我们创建,并且传递给我们
    
    - (void)drawRect:(CGRect)rect
    {
        CGFloat radius=rect.size.width*0.5;
        CGPoint center=CGPointMake(radius, radius);
        //-M_PI_2 开始弧度圆的定点
        //_progress*M_PI*2  _progress百分多少 M_PI*2 360度
        CGFloat endA = -M_PI_2 + _progress*M_PI*2;
        UIBezierPath*path=[UIBezierPath bezierPathWithArcCenter:center radius:radius-2 startAngle:-M_PI_2 endAngle:endA clockwise:YES];
        [path stroke];
    }
    

    画饼状图

    - (void)drawRect:(CGRect)rect
    {
        NSArray*arr=@[@36,@34,@30];
        CGFloat radius=rect.size.width*0.5;
        CGPoint center=CGPointMake(radius, radius);
        CGFloat startA=0;
        CGFloat endA=0;
        CGFloat angle=0;
        for (int i=0; i<arr.count; i++)
        {
            startA=endA;
            angle=[arr[i] doubleValue]/100.0*M_PI*2;
            endA=startA+angle;
            UIBezierPath*path=[UIBezierPath bezierPathWithArcCenter:center radius:radius-2 startAngle:startA endAngle:endA clockwise:YES];
            [path addLineToPoint:center];
            [[self colorRandom] set];
            [path fill];
        }
    }
    -(UIColor*)colorRandom
    {
        CGFloat r=arc4random_uniform(256)/255.0;
        CGFloat g=arc4random_uniform(256)/255.0;
        CGFloat b=arc4random_uniform(256)/255.0;
        return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
    }
    
    

    画柱状图

    - (void)drawRect:(CGRect)rect
    {
        NSArray*arr=@[@36,@34,@30];
        CGFloat w=rect.size.width/(2*arr.count-1);
        CGFloat x=0;
        CGFloat y=0;
        CGFloat h=0;
        for (int i=0; i<arr.count; i++)
        {
            x=2*w*i;
            h=[arr[i] floatValue]/100.0 *rect.size.height;
            y=rect.size.height-h;
            UIBezierPath*path=[UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];
            [[self colorRandom] set];
            [path fill];
        }
    }
    -(UIColor*)colorRandom
    {
        CGFloat r=arc4random_uniform(256)/255.0;
        CGFloat g=arc4random_uniform(256)/255.0;
        CGFloat b=arc4random_uniform(256)/255.0;
        return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
    }
    

    NSTimer

    //NSTimer很少用于绘画,因为调度优先级比较低,并不会准时调用
    -(void)awakeFromNib
    {
    //    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
        CADisplayLink*link=[CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];
        //想让定时器工作,必须得要把它添加到主运行循环
        [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }
    //在绘图当中, 我们一般使用CADisplayLink.因为他和setNeedsDisplay调用时机是一样的,都是当下一次屏幕刷新的时候调用.
    //CADisplayLink:每次屏幕刷新的时候就会调用,屏幕一般一秒刷新60次
    -(void)timeChange
    {
        //注意:这个方法并不会马上调用drawRect,其实这个方法只是给当前控件添加刷新的标记,等下一次屏幕刷新的时候才会调用drawRect
        [self setNeedsDisplay];
    }
    

    相关文章

      网友评论

          本文标题:drawRect:自定义view的绘图

          本文链接:https://www.haomeiwen.com/subject/vgolbttx.html