对于日常的开发我们一般用不到Quzrtz,不过当我们需要设计的一些奇葩的图像图形的的时候,这时候Core Graphics 就有很大的作用了。
举个🌰:imageView layer圆角,离屏渲染影响性能,好嘛,不用了!直接用CG设置图片圆角。妈妈在也不不怕爱啪啪帧数低了。
经理又觉得你的提示框方方正正太丑了,要来点个性的。没办法只能改嘛,怎么改?找CG啊!
现在,我们一点一点来看这个Quzrtz是个什么鬼。
前提准备
//热身运动
//获取上下文环境
CGContextRef ctx = UIGraphicsGetCurrentContext();
//设置画环境中线的颜色
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
===
===
//填充路径
CGContextStrokePath(ctx);
上面的3步,是必不可少的。当然绘制的内容,我们一点一点说。
绘制lines
//获取上下文环境
CGContextRef ctx = UIGraphicsGetCurrentContext();
//设置画环境中线的颜色
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
//设置回执起点
CGContextMoveToPoint(ctx, 10, 10);
CGPoint points[] = {
CGPointMake(20, 20),
CGPointMake(30, 30),
CGPointMake(40, 40),
CGPointMake(50, 50),
CGPointMake(60, 70),
CGPointMake(80, 80),
};
//连续绘制路径
CGContextAddLines(ctx, points, sizeof(points)/sizeof(points[0]));
//填充路径
CGContextStrokePath(ctx);
CGPoint points1[] = {
CGPointMake(120, 20),
CGPointMake(130, 30),
CGPointMake(140, 40),
CGPointMake(150, 50),
CGPointMake(160, 70),
CGPointMake(180, 80),
};
//分段绘制路径
CGContextStrokeLineSegments(ctx, points1, sizeof(points1)/sizeof(points1[0]));
CGContextStrokePath(ctx);
上面 2种线条的效果图
对于线条还可以设置一些属性
1.宽度(必须的0.0)
CGContextSetLineWidth(ctx, 10);
2.设置line cap 就是线条棱角的样式(3种样式)
typedef CF_ENUM(int32_t, CGLineCap) {
kCGLineCapButt,
kCGLineCapRound,
kCGLineCapSquare
};
3.设置line join 线衔接的样式(线的宽度 达到一定的程度,才会看得出来)
typedef CF_ENUM(int32_t, CGLineJoin) {
kCGLineJoinMiter,
kCGLineJoinRound,
kCGLineJoinBevel
};
CGContextSetLineJoin(ctx, kCGLineJoinRound);
对了,还有重要的一点,如果你想两段 线条之间设置的属性不相关的话
要讲content保存到堆栈中
CGContextSaveGState(context);
CGContextRestoreGState(context);
还有一点上面的path 路径。完全可以用贝塞尔代替,写出一些比较奇葩的弧度0。o
炫酷的定制dash
CGContextSaveGState(ctx);
CGFloat phase[] = {25.0,5.0};//设置宽度间隙 可以根据需求设置不同的数字
CGContextSetLineDash(ctx, _phase, phase, 2);//主要phase 设置的不通,这个东西介意跑起来哦
//下面就没什么好说的了,就是画一个笑脸
CGContextAddRect(ctx, CGRectMake(100, 100, 200, 200));
CGContextAddEllipseInRect(ctx, CGRectMake(130, 130, 50, 50));
CGContextAddEllipseInRect(ctx, CGRectMake(210, 130, 50, 50));
CGContextAddRect(ctx, CGRectMake(140, 230, 120, 40));
CGContextSetLineWidth(ctx, 5);
CGContextStrokePath(ctx);
CGContextRestoreGState(ctx);
不断绘制的话,就会有这个效果
是不是很帅!
只要phase变化,不停的重绘就可以了
- (void) setPhase:(CGFloat)phase {
if (_phase != phase) {
_phase = phase;
[self setNeedsDisplay];
}
}
线是基础,不同的线可以组成不同图形,内部还提供了Rect(矩形)Arcs(圆弧) Curve(曲线)以及对应的不同模式等等方法大家可以尝试一下。
绘制一张图片
UIImage *image = [UIImage imageNamed:@"1.jpg"];
CGContextDrawImage(ctx, CGRectMake(100, 300, 50, 50), image.CGImage);
由于坐标系统设定的不一样,这张图片绘制完,其实是倒着的。
还有一个平铺图片的方法
CGContextDrawTiledImage
毕竟倒着看,难受的要死。
苹果也给了方法解决他,就是旋转
CGContextTranslateCTM(ctx, 0, self.bounds.size.height);
CGContextScaleCTM(ctx, 1, -1);
绘制pdf
//获取pdf
CGPDFPageRef page = CGPDFDocumentGetPage(self.pdfDocument, 1);
//适应屏幕
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, self.bounds, 0, true);
CGContextConcatCTM(context, pdfTransform);
//绘制
CGContextDrawPDFPage(context, page);
绘制文字
其实 都是差不多意思
这边再说说一下,Clipping和Masking
//集合上面的绘制line 和 图片 之后调用下面这个方法就能clip
CGContextClip();
CGContextClipToMask()//
是时候解决上面的问题了
裁剪图片圆角
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//绘制裁剪的贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:radius];
CGContextAddPath(ctx, path.CGPath);
CGContextClip(ctx);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
// CGContextDrawPath(ctx, kCGPathFillStroke);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
上面的path 我使用贝塞尔做的,感觉这样简单
之后调用contentClip
去裁剪。
恩,下班了,暂时写到这。。0.0