标签: 裁剪、多边形、绘制图片、绘制文字、截图、曲线、扇形、椭圆、直线
绘图基本格式
- (void)drawRect:(CGRect)rect{
// 只有在drawRect中才能获得跟View相关联的图形上下文,系统会在视图将要显示时自动调用这个方法;
// 获取绘图上下文,在drawRect方法中获取的是layer的上下文。
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Fill ——> 填充
// Stroke ——> 空心
}
一、绘制直线(虚线为多条直线的集合)
// 方法一
// 1.获取绘图上下文,在drawRect方法中获取的是layer的上下文。
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
CGMutablePathRef path = CGPathCreateMutable();
// 3.设置起始点(注意NULL只能手动输入大写,不会提示)
CGPathMoveToPoint(path, NULL, 50, 50);
// 4.添加结束点
CGPathAddLineToPoint(path, NULL, 80, 50);
// 5.添加路径到上下文
CGContextAddPath(ctx, path);
// 6.进行渲染显示
CGContextStrokePath(ctx);
// 方法二:系统自动创建路径
CGContextRef ctx2 = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(ctx2, 40, 40);
CGContextAddLineToPoint(ctx2, 80, 40);
CGContextStrokePath(ctx2);
// 方法三:纯UI框架
// 4.内部自动获得上下文,用UI框架画图
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:CGPointMake(60, 60)];
[path1 addLineToPoint:CGPointMake(70, 70)];
[path1 stroke];
// 方法四:UI框架与CG框架结合
CGContextRef ctx3 = UIGraphicsGetCurrentContext();
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(60, 80)];
[path2 addLineToPoint:CGPointMake(70, 80)];
CGContextAddPath(ctx3, [path2 CGPath]);
// UIKit 转到CG框架
CGContextStrokePath(ctx3);
二、绘制曲线
// 获取图形上下文
CGContextRef ctx4 = UIGraphicsGetCurrentContext();
// 画曲线(设置起点)
CGContextMoveToPoint(ctx4, 20, 100);
// 设置控制点和终点
// 三次曲线函数
// CGContextAddCurveToPoint(ctx4, 50, 80, 50 , 80, 100, 100);
// 二次曲线函数
CGContextAddQuadCurveToPoint(ctx4, 50, 150, 100, 100);
CGContextStrokePath(ctx4);
三、绘制多边形
// 常规画法
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 起始点
CGContextMoveToPoint(ctx, 30, 30);
// 终点
CGContextAddLineToPoint(ctx, 60, 60);
// 第二条线的终点
CGContextAddLineToPoint(ctx, 70, 20);
// 设置设置RGB颜色
CGContextSetRGBStrokeColor(ctx, 1.0, 1.0, 0.7, 1.0);
// 设置线宽
CGContextSetLineWidth(ctx, 12);
// 设置线条头尾->圆角
CGContextSetLineCap(ctx, kCGLineCapRound);
// 设置线条转角->圆角
CGContextSetLineJoin(ctx, kCGLineJoinRound);
// 绘制一条空心的线
CGContextStrokePath(ctx);
// 绘制矩形
CGContextRef ctx1 = UIGraphicsGetCurrentContext();
CGContextAddRect(ctx1, CGRectMake(130, 20, 50, 120));
[[UIColor grayColor] setFill];
// 设置实心颜色
[[UIColor redColor] setStroke];
// 设置空心颜色;
[[UIColor blueColor] setFill];
// 渲染
CGContextFillPath(ctx1);
// 画一个圆角矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 140) cornerRadius:15];
四、绘制扇形、圆弧
// 获取图形上下文
CGContextRef ctx4 = UIGraphicsGetCurrentContext();
// 画扇形
// 设置圆心及圆弧起始终止弧度,顺时针逆时针;
CGContextAddArc(ctx4, 20, 20, 50, 0, M_PI_2, 0);
// 绘制弧形终点到圆心的线
CGContextAddLineToPoint(ctx4, 20, 20);
// 渲染会自动闭合图形
CGContextFillPath(ctx4);
五、绘制椭圆
CGContextRef ctx2 = UIGraphicsGetCurrentContext();
CGContextFillEllipseInRect(ctx2, CGRectMake(130, 20, 50, 120));
CGContextFillPath(ctx2);
或者
CGContextAddEllipseInRect(ctx2, CGRectMake(130, 20, 50, 120));
六、绘制文字
// 绘制文字用OC方法,用C非常非常的麻烦
NSString *str = @"你好";
// OC方法中自动获取了上下文,也自动封装了渲染
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 创建一个带有字符属性的字典
dict[NSBackgroundColorAttributeName] = [UIColor redColor];
// 将文字指定到点,不换行
[str drawAtPoint:CGPointMake(130, 130) withAttributes:dict];
// 将文字指定到矩形中,会自动换行。
// [str drawInRect:CGRectMake(50, 50, 20, 100) withAttributes:dict];
//会自动渲染
七、绘制图片
UIImage *img = [UIImage imageNamed:@"1"];
// 指定到点,图片有多大,显示多大
[img drawAtPoint:CGPointMake(10, 10)];
// 指定到范围,图片会拉伸,以完全显示
[img drawInRect:CGRectMake(20, 20, 100, 100)];
// 平铺原有图片,n个图片拼接而成,可以用来做背景,实现很小的图片填充满整个背景
[img drawAsPatternInRect:CGRectMake(20, 20, 100, 100)];
// 图形上下文栈(保存最纯洁图形上下文)
// 保存最纯洁的图形上下文到栈顶
CGContextSaveGState(ctx);
// 取出保存的纯洁的图形上下文,并且覆盖当前上下文
CGContextRestoreGState(ctx);
八、矩阵操作
// 一定要在添加路径之前调用
// 平移
CGContextTranslateCTM(ctx2, 20, 30);
// 缩放
CGContextScaleCTM(ctx2, 1.2, 1.2);
// 旋转图片裁剪
CGContextRotateCTM(ctx2, M_PI_2);
九、定时器及重绘
// 简易定时器,时间不精确,在0.1s以上,触发时间不规则
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
// 每次屏幕刷新都会调用,每秒刷新60次,setNeedsDisplay调用这个方法,并不会立即刷新,而是底层会给这个View加一个重绘的标记,在下一次屏幕刷新的时候自动生成上下文,进行重绘(执行drawRect方法);
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
十、裁剪
// 设置裁剪区域
UIBezierPath *clipPath = [UIBezierPath bezierPathWithOvalInRect:imageRect];
// 添加裁剪区域
[clipPath addClip];
// 先进行裁剪,裁剪只会影响到后面绘制的东西
UIRectClip(CGRectMake(30, 30, 70, 80));
// 按照rect裁剪图片
// 将一张大图进行裁切,以设置按钮上的图片
CGRect rect = CGRectMake(i *clipW, 0, clipW, clipH);
CGImageRef img = CGImageCreateWithImageInRect(bigImage.CGImage, rect);
CGImageRef imgSel = CGImageCreateWithImageInRect(bigSelImage.CGImage, rect);
// 设置按钮的图片
btn.contentMode = UIViewContentModeCenter;
[btn setImage:[UIImage imageWithCGImage:img] forState:UIControlStateNormal];
[btn setImage:[UIImage imageWithCGImage:imgSel] forState:UIControlStateSelected];
十一、截图
// 开启图形上下文(no 代表透明,不透明度为0)
// 如果要求上下文和截图尺寸一样大,那就可以用不透明NO。
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
// 获取图层上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 渲染 (位图的渲染用renderINContext,将图层渲染到图形上下文,layer只能渲染,不能重绘)
[view.layer renderInContext:ctx];
// 获取图片(从当前图形上下文获取图片)
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图形上下文
UIGraphicsEndImageContext();
// 图片保存,做图片的压缩,直接设置图片质量最小
// UIImageJPEGRepresentation:
NSData *data = UIImagePNGRepresentation(image);
// atomically 原子性,如果是YES,那么存储就有缓存,不会有存一半的现象
[data writeToFile:@"/Users/apple/Desktop/1.png" atomically:YES];