iOS 开发~项目常用,经典内容收集iOS 项目技巧技术重塑

iOS CGContextRef&CGMutablePa

2017-07-14  本文已影响260人  SunshineBrother

简单的四句介绍

Quartz是一个二维绘图引擎,使用的是CoreGraphics库,同时支持iOS和Mac系统

CGContextRef:获取图形上下文.或者叫作用域,即画布,他是专门用来保存绘画期间的各种数据的

UIBezierPath是对CGPathRef的封装。创建矢量图形时,拆解成一条或者多条线段,拼接起来,每条下端的终点都是下一条线段的起点

当我们绘制路径时,Path的信息就会被Graphics context重置。 如果我们想要保存path信息,并多次使用它,我们就可以用到CGPathCreatMutable申请路径,然后用CGPathAddLintToPoint等方法来添加路径。

1.设置点和线

介绍属性
CGContextRef UIBezierPath CGMutablePathRef
CGContextMoveToPoint moveToPoint CGPathMoveToPoint
CGContextAddLineToPoint addLineToPoint CGPathAddRect
CGContextAddRect bezierPathWithRect CGPathAddRect
CGContextAddEllipseInRect bezierPathWithOvalInRect CGPathAddEllipseInRect
CGContextAddArc addArcWithCenter CGPathAddArcToPoint
CGContextAddQuadCurveToPoint addQuadCurveToPoint CGPathAddQuadCurveToPoint
CGContextAddCurveToPoint addCurveToPoint CGPathAddCurveToPoint

2、设置线的属性

这些设置线属性的API都是通用的

思维导图

基础绘图.png

CGContextRef介绍

需要代码的请参考这里

52C4C92C-D5C3-45A2-A05A-B25943165601.png
Quartz2d是一个二维绘图引擎,使用的是CoreGraphics库,同时支持iOS和Mac系统

有点难,比较底层,操作系统层api一般都是纯C开发的,有针对性的开发才会用到

要基于UIView去开发

实战用途

画线段

画三角形

画矩形
画圆
画扇形
画曲线
画特效
绘制文字
绘制图片
变换运用(改变画布位置)
1、CGContextRef之画线段

CGContextRef 具有贯穿全局的效果,我们设置一个全局变量创建 一次 就可以了

虚线
- (void)drawLine1{
    //获取图形上下文.或者叫作用域,即画布,他是专门用来保存绘画期间的各种数据的
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    //路径设置
    //先设置一个起点
    CGContextMoveToPoint(contextRef, 50, 100);
    //设置终点
    CGContextAddLineToPoint(contextRef, 100, 500);
    
    //设置样式
    //设置线宽
    CGContextSetLineWidth(contextRef, 5.0f);
    //设置线的颜色
    CGContextSetStrokeColorWithColor(contextRef, [UIColor redColor].CGColor);
    
    //风格  头部和尾部的处理
    CGContextSetLineCap(contextRef, kCGLineCapRound);
    
    
    /*
     画虚线
     参数1 作用域
     参数2 起点的偏移量
     参数3 指明虚线是如何交替绘制
     lengths的值{10,10}表示先绘制10个点,再跳过10个点
     如果把lengths值改为{10, 20, 10},则表示先绘制10个点,跳过20个点,绘制10个点,跳过10个点,再绘制20个点,
     参数4 实心部分和虚心部分的循环次数
     */
    CGFloat lenths[] = {10, 10};
    CGContextSetLineDash(contextRef, 0, lenths, 2);
    
    
    //渲染
    CGContextStrokePath(contextRef);
}

效果图

屏幕快照 2017-07-14 上午10.17.30.png
2、CGContextRef之画多边形
画三角形
- (void)drawTriangle{
    //获取图形上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    //设置点
    CGContextMoveToPoint(contextRef, 100, 100);
    CGContextAddLineToPoint(contextRef, 200, 200);
    CGContextAddLineToPoint(contextRef, 100, 200);
    
    //把点封闭起来
    CGContextClosePath(contextRef);
    
    //设置线宽
    CGContextSetLineWidth(contextRef, 3.0f);
    //设置线的颜色
    CGContextSetStrokeColorWithColor(contextRef, [UIColor redColor].CGColor);
    //设置填充颜色
    CGContextSetFillColorWithColor(contextRef, [UIColor greenColor].CGColor);
    
    
    // 如果写了多种渲染方式,那么只执行第一种
//    CGContextStrokePath(contextRef);
//    CGContextFillPath(contextRef);
    
    CGContextDrawPath(contextRef, kCGPathFillStroke);
 
}

效果图


屏幕快照 2017-07-14 上午10.19.41.png
画正方形
//获取图形上下文
   CGContextRef contextRef = UIGraphicsGetCurrentContext();
   
   CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));
   
   //颜色的填充
   CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
   //线宽
   CGContextSetLineWidth(contextRef, 4.0f);
   CGContextSetStrokeColorWithColor(contextRef, [UIColor blueColor].CGColor);
   
   //渲染
   CGContextDrawPath(contextRef, kCGPathFillStroke);

效果图


屏幕快照 2017-07-14 上午10.20.33.png
3、CGContextRef之画曲线
画圆
  // 绘制图形上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    CGContextAddEllipseInRect(contextRef, CGRectMake(100, 100, 100, 100));
    
    CGContextDrawPath(contextRef, kCGPathFillStroke);

扇形
- (void)drawArc1{
    
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    /*
     参数1:作用域
     参数2:圆心x坐标
     参数3:圆心y坐标
     参数4:半径
     参数5:开始角度
     参数6:结束角度
     参数7:方向,0表示顺时针,1表示逆时针
     
     */
    CGContextAddArc(contextRef, 100, 200, 100, 0, M_PI_4, 0);
    
    CGContextSetLineWidth(contextRef, 5.0f);
    CGContextSetFillColorWithColor(contextRef, [UIColor greenColor].CGColor);
    CGContextSetStrokeColorWithColor(contextRef, [UIColor redColor].CGColor);
    
    
//    CGContextAddLineToPoint(contextRef, 100, 200);
    
    CGContextDrawPath(contextRef, kCGPathFillStroke);
    
    
}




- (void)drawArc2{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    
    //第一部分
    CGContextMoveToPoint(contextRef, 250, 400);
    CGContextAddArc(contextRef, 250, 400, 100, 0, M_PI_2, 0);
    CGContextSetFillColorWithColor(contextRef, [UIColor blueColor].CGColor);
    CGContextFillPath(contextRef);
    
    
    //第二部分
    CGContextMoveToPoint(contextRef, 250, 400);
    CGContextAddArc(contextRef, 250, 400, 100, M_PI_2, M_PI_2/2*3, 0);
    CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
    CGContextFillPath(contextRef);
    
    // 第三部分
    CGContextMoveToPoint(contextRef, 250, 400);
    CGContextAddArc(contextRef, 250, 400, 100, 0, 225*M_PI/180.0, 1);
    CGContextSetFillColorWithColor(contextRef, [UIColor purpleColor].CGColor);
    CGContextFillPath(contextRef);

    
}

效果图


屏幕快照 2017-07-14 上午10.22.57.png
画曲线
   
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    //起点
    CGContextMoveToPoint(contextRef, 20, 300);
    /*
     三阶贝塞尔曲线
     参数1:作用域
     参数2:控制点x
     参数3:控制点y
     参数4:控制点x
     参数5:控制点y
     参数6:终点x
     参数7:终点y
     
     - `CGContextAddQuadCurveToPoint`  二阶贝塞尔曲线
     */
    CGContextAddCurveToPoint(contextRef, 100, -100, 200, 900, 300, 400);
     CGContextStrokePath(contextRef);    

效果图

屏幕快照 2017-07-14 上午10.24.32.png
4、CGContextRef之画特效
 CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    
    CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));
    CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
    CGContextSetStrokeColorWithColor(contextRef, [UIColor greenColor].CGColor);
    CGContextSetLineWidth(contextRef, 5.0f);
    
    //设置透明度
    //取值范围(0~1,0表示全透明,1是不透明)
     CGContextSetAlpha(contextRef, 1);
    
    /*
     设置阴影
     参数1:画布
     参数2:右偏移量
     参数3:下偏移量
     参数4:模糊度(0是不模糊,越大越模糊,10就差不多)
     */
    CGContextSetShadow(contextRef, CGSizeMake(10, 10), 10);
    
    
    CGContextDrawPath(contextRef, kCGPathFillStroke);

效果图


屏幕快照 2017-07-14 上午10.25.44.png
5、CGContextRef之绘制
绘制文字
 NSDictionary *dic = @{
                          NSFontAttributeName:[UIFont systemFontOfSize:15],
                           NSForegroundColorAttributeName : [UIColor redColor]
                          };
    // 两种的区别drawInRect会自动换行,drawAtPoint:CGPointZero不会自动换行
    [text drawInRect:CGRectMake(20, 100, self.bounds.size.width - 40, 100) withAttributes:dic];
//    [text drawAtPoint:CGPointMake(20, 200) withAttributes:dic];
绘制图片
- (void)drawImage{
    UIImage *image = [UIImage imageNamed:@"image.jpg"];
    [image drawInRect:CGRectMake(100, 100, 250, 250)];
    // 平铺图像,超出部分会自动剪裁
//    [image drawAsPatternInRect:self.bounds];
    // 如果实现文字和图片共存,需要将文字写在后面,防止被图片盖住
    NSDictionary *dic = @{
                          NSFontAttributeName:[UIFont systemFontOfSize:15],
                          NSForegroundColorAttributeName : [UIColor redColor]
                          };
    NSString *text = @"如果实现文字和图片共存,需要将文字写在后面,防止被图片盖住";
    [text drawInRect:CGRectMake(100, 300, 250, 100) withAttributes:dic];
}

-(void)clipImage{
    /*
     思路:先画一个圆,让图片显示在圆的内部,超出的部分不显示。
     注意:显示的范围只限于指定的剪切范围,无论往上下文中绘制什么东西,只要超出了这个范围的都不会显示。
     */
    
    
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    // 先画一个圆形
    CGContextAddEllipseInRect(contextRef, CGRectMake(100, 400, 200, 200));
    
    // 切割操作
    CGContextClip(contextRef);
    CGContextFillPath(contextRef);
    
    
    UIImage *image = [UIImage imageNamed:@"image.jpg"];
    [image drawInRect:CGRectMake(100, 400, 200, 200)];
    

}


效果图


屏幕快照 2017-07-14 上午10.28.28.png
5、CGContextRef之图形变换
 
    UIImage *image0 = [UIImage imageNamed:@"image.jpg"];
    [image0 drawInRect:CGRectMake(300, 400, 100, 100)];
    
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    // 移动变换
    //    CGContextTranslateCTM(contextRef, -100, -100);
    /**
     *  对象沿着x轴移动-100单位,沿着y轴移动-100单位
     */
    // 多个变换会叠加
    // 缩放
    //    CGContextScaleCTM(contextRef, 0.5, 0.5);
    
    // 获取中心点
//    CGFloat cenX = CGRectGetMidX(self.bounds);
//    CGFloat cenY = CGRectGetMidY(self.bounds);
//    
    
    // 先移动一下
    //    CGContextTranslateCTM(contextRef, cenX, cenY);
    CGContextTranslateCTM(contextRef, 100+100/2.0, 100+100/2.0);
    
    // 旋转变换
    CGContextRotateCTM(contextRef, M_PI_4);
    // 再移动回去
    CGContextTranslateCTM(contextRef, -(100+100/2.0), -(100+100/2.0));
    
    /**
     *  旋转可以认为实质是旋转坐标系,会绕着坐标原点旋转,可以先将坐标原点移动到要旋转的图形的中点,然后执行旋转,然后再移动回来,实现绕着图形中心旋转的目的
     */
    
    
    UIImage *image = [UIImage imageNamed:@"image.jpg"];
    [image drawInRect:CGRectMake(300, 400, 100, 100)];
    

效果图

屏幕快照 2017-07-14 上午10.29.55.png

UIBezierPath

使用步骤

常用API
代码就不都贴出来了,想要了解的可以点击这里下载源文件。最近会一直研究一些动画方面的知识,想要和我一同学习的,可以点击关注
EB6A7927-0FDA-4C47-AAEF-5C6B41C98C0F.png

参考链接
Quartz 2D学习(一)简单绘制图形
iOS的UIBezierPath类和贝塞尔曲线

上一篇 下一篇

猜你喜欢

热点阅读