iOS--玩玩苹果的绘制(Quartz)

对于日常的开发我们一般用不到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);
0F0C3C50-1D82-49B2-A6F9-F649CAB6983F.png

上面 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);
8BD3D836-46D0-43F2-AD38-C8D634EEB65C.png

对了,还有重要的一点,如果你想两段 线条之间设置的属性不相关的话

要讲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);

不断绘制的话,就会有这个效果

CGdash.gif

是不是很帅!
只要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);

由于坐标系统设定的不一样,这张图片绘制完,其实是倒着的。


0D01111E-D181-4166-9769-02D98E0429AE.png

还有一个平铺图片的方法

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

你可能感兴趣的:(iOS--玩玩苹果的绘制(Quartz))