Quartz2D

2016-09-01  本文已影响80人  Mario_ZJ

什么是Quartz2D

Quartz2D的应用

Quartz2D中的图形上下文是什么,有哪些类型

自定义UIView的步骤

基本线条的绘制

线段的绘制

-(void)drawRect:(CGRect)rect {
    //1.获取当前上下文(uigraphics开头)
    CGContextRef ctx =  UIGraphicsGetCurrentContext();

    //2.描述路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    //2.1设置起点
    [path moveToPoint:CGPointMake(50, 200)];
    //2.1添加一根线到终点
    [path addLineToPoint:CGPointMake(200, 50)];

    //3.把绘制的路径添加到上下文
    //UIBezierPath=UIKit ->   CGPathRef=coreGraphics(将UIKit类型的path转换为CGPathRef类型的path)
    CGContextAddPath(ctx, path.CGPath);
    
    //4.把上下文的内容渲染UIView的layer.(stoke(描边),fill(填充))
    CGContextStrokePath(ctx);   
}
设置线的宽度
CGContextSetLineWidth(ctx, 10);
设置线的连接样式.
CGContextSetLineJoin(ctx, kCGLineJoinBevel);
设置线的顶角样式
CGContextSetLineCap(ctx, kCGLineCapRound);
设置线的颜色.还可以直接用set这种方法
[[UIColor greenColor] set];   

曲线的绘制

-(void)drawQuadCurve {
    //1.获取当前上下文(uigraphics开头)
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //2.描述路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(50, 250)];
    //添加一根曲线
    [path addQuadCurveToPoint:CGPointMake(250, 250) controlPoint:CGPointMake(150, 50)];
    
    //3.把绘制的路径添加到上下文
    //UIBezierPath=UIKit ->   CGPathRef=coreGraphics
    CGContextAddPath(ctx, path.CGPath);
    
    //4.把上下文的内容渲染到View的layer
    CGContextStrokePath(ctx);
}

矩形的绘制

 //画矩形
- (void)drawRect {
    //1.获取上下文
    CGContextRef ctx =  UIGraphicsGetCurrentContext();

    //2.描述路径
    /*
    (x,y)点决定了矩形左上角的点在哪个位置
    (width,height)是矩形的宽度高度
    */
    // 普通的矩形 (bezierPathWithRect:)
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
    
    //圆角矩形 (bezierPathWithRoundedRect:cornerRadius:)
    //cornerRadius:圆角半径
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 200) cornerRadius:100];

    //单独设置某一角的圆角(bezierPathWithRoundedRect:byRoundingCorners:cornerRadius:)
    UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 100) byRoundingCorners:UIRectCornerTopLeft cornerRadius:CGSizeMake(10, 20)];    

    //设置线段的颜色
    [[UIColor yellowColor] set];
    //3.把路径添加到上下文
    CGContextAddPath(ctx, path.CGPath);
    //4.把上下文的内容渲染View的layer
    CGContextFillPath(ctx);
}

椭圆形的绘制

    //画椭圆形 bezierPathWithOvalInRect:
    //1.获取上下文
    CGContextRef ctf = UIGraphicsGetCurrentContext();
    //2.描述路径
    UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 200, 100)];
    //3.把路径添加到上下文
    CGContextAddPath(ctf, path.CGPath);
    //4.把上下文的内容渲染View的layer
    CGContextStrokePath(ctf);

弧形的绘制

//画弧
-(void)drawRect:(CGRect)rect
{
    //Center:圆心
    //radius:半径
    //startAngle:开始角度,0度在圆的最右侧.往下,角度为正,往上,角度为负
    //endAngle:截至角度
    //clockwise:是否为顺时针方向
    CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);
    
    CGFloat radius = rect.size.width * 0.5 - 10;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
    
    [path stroke];   
}

扇形的绘制

//先绘制一个弧形
    //设置弧形的中心点
    CGPoint center = CGPointMake(self.bounds.size.width * 0.5, rect.size.height * 0.5);
    //设置弧形的半径
    CGFloat radius = rect.size.width * 0.5 - 10;
    //绘制弧形曲线
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
//绘制扇形
    //添加一根线到圆心
    [path addLineToPoint:center];
    [[UIColor redColor] set];
    //关闭路径(自动从终点连接一根线到起点.)
    [path closePath];
    //渲染到view的layer上
    [path stroke];
//先绘制一个弧形
    //设置弧形的中心点
    CGPoint center = CGPointMake(self.bounds.size.width * 0.5, rect.size.height * 0.5);
    //设置弧形的半径
    CGFloat radius = rect.size.width * 0.5 - 10;
    //绘制弧形曲线
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO];
//绘制扇形
    //添加一根线到圆心
    [path addLineToPoint:center];
    [[UIColor redColor] set];
    //填充模式会自动关闭路径
    [path fill];

图形的绘制以及渲染的方式

```
以弧形绘制的代码为例:
// 1.获取上下文
CGContextRef ctf = UIGraphicsGetCurrentContext();
// 2.绘制路径
UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.width * 0.5) radius:100 startAngle:0 endAngle:M_PI clockwise:YES];
// 3.将路径添加到上下文
CGContextAddPath(ctf, path.CGPath);
// 4.将上下文中的内容渲染到View的Layer上
CGContextStrokePath(ctf);
```

绘制文字

    //1.设置要绘制的文字
    NSString * str = @"绘制文字练习绘制文字练习绘制文字练习绘制文字练习绘制文字练习";

    //2.设置文字的属性,通过Attribute设置
    NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
    //设置文字字体
    dict[NSFontAttributeName] = [UIFont systemFontOfSize:45];
    //设置文字颜色
    dict[NSForegroundColorAttributeName] = [UIColor yellowColor];
    //设置文字边的宽度
    dict[NSStrokeWidthAttributeName] = @5;
    //设置文字的描边
    dict[NSStrokeColorAttributeName] = [UIColor greenColor];
    //设置文字的阴影
    NSShadow * shadow = [[NSShadow alloc] init];
    shadow.shadowColor = [UIColor cyanColor];
    shadow.shadowOffset = CGSizeMake(10, 10);
    shadow.shadowBlurRadius = 10;
    dict[NSShadowAttributeName] = shadow;

    //3.将文字绘制到当前view 的layer上
    [str drawAtPoint:CGPointZero withAttributes:nil];
    [str drawInRect:rect withAttributes:dict];

绘制图片

绘制图片同样开始要先把图片素材导入.

    //1.加载图片
    UIImage *image = [UIImage imageNamed:@"001"];

    //会把超过裁剪区域以外的内容给裁剪掉/必须得要在绘制之前设置裁剪区域
    UIRectClip(CGRectMake(0, 0, 50, 50));

    //drawAtPoint:绘制的是原始图片的尺寸大小.
    [image drawAtPoint:CGPointZero];
    //把绘制的图片填充到给的区域当中.
    [image drawInRect:rect];

    //平铺
    [image drawAsPatternInRect:rect];

    [[UIColor redColor] set];
    //快速填充一个区域
    UIRectFill(CGRectMake(50, 50, 100, 100));

模拟系统的UIImageView

#import <UIKit/UIKit.h>
@interface ZHJImageView : UIView

//用于接收外界传入的图片
@property (nonatomic, strong) UIImage * image;
//在初始化View的时候,将view的尺寸设置为传入的image的尺寸
-(instancetype)initWithImage:(UIImage *)image;

@end
@implementation ZHJImageView

//当image属性接收到传入的图片的时候,立刻调用drawRect方法,进行重绘
-(void)setImage:(UIImage *)image
{
    _image = image;
//重绘
    [self setNeedsDisplay];
}

//初始化的时候,让当前view的尺寸等于传入的图片的尺寸
-(instancetype)initWithImage:(UIImage *)image{
    if (self = [super init]) {
        //将图片赋值给image属性,并在属性的set方法中重绘
        _image = image;
        self.frame = CGRectMake(0, 0, self.image.size.width, self.image.size.height);
    }
    return self;
}

//将传入的图片绘制到view的layer上
-(void)drawRect:(CGRect)rect
{
    [self.image drawInRect:rect];
}

@end

CADisplayLink的使用(雪花飘落)

#import "SnowFlowView.h"
@implementation SnowFlowView
//因为这个view是从storyboard中加载的,所以将添加子控件的代码写在awakeFromNib中
-(void)awakeFromNib
{
    //创建定时器
    CADisplayLink * link = [CADisplayLink displayLinkWithTarget:self selector:@selector(flowSnow)];
    //将定时器加入到主线程中
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

//定义另个静态全局变量,用于保存图片位置
static int snowX = 0;
static int snowY = 0;
//定时器方法
-(void)flowSnow{
    //实现雪花下落的效果
    snowX += 1;
    if (snowX >= [UIScreen mainScreen].bounds.size.width) {
        snowX = 0;
    }
    snowY += 10;
    if (snowY >= [UIScreen mainScreen].bounds.size.height) {
        snowY = 0;
    }
    //重绘
    [self setNeedsDisplay];
}

//将雪花图片绘制到当前的view上
-(void)drawRect:(CGRect)rect
{
    UIImage * image = [UIImage imageNamed:@"雪花"];
    [image drawAtPoint:CGPointMake(snowX, snowY)];
}
@end

图形上下文状态栈

-(void)drawRect:(CGRect)rect
{
    //绘制第一条线
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    UIBezierPath * path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(20, 150)];
    [path addLineToPoint:CGPointMake(280, 150)];
    
    //第一次设置图形上下文的状态
    CGContextSetLineWidth(ctx, 10);
    [[UIColor cyanColor] set];
    CGContextSaveGState(ctx);//保存第一次设置的上下文的状态
    
    //第二次设置图形上下文的状态
    CGContextSetLineWidth(ctx, 5);
    [[UIColor greenColor] set];
    CGContextSaveGState(ctx);//保存第二次设置的上下文的状态
    
    //渲染第一次绘制的路径
    CGContextAddPath(ctx, path.CGPath);
    CGContextStrokePath(ctx);
    
    //绘制第二条线
    UIBezierPath * path1 = [[UIBezierPath alloc] init];
    [path1 moveToPoint:CGPointMake(150, 20)];
    [path1 addLineToPoint:CGPointMake(150, 280)];
    
    //从位图上下文状态栈中取出位图上下文的状态(取出第一次保存的位图上下文的状态)
    CGContextRestoreGState(ctx);//取出第二次图形上下文的状态
    CGContextRestoreGState(ctx);//取出第一次图像上下文的状态
    
    //渲染第二次绘制的路径
    CGContextAddPath(ctx, path1.CGPath);
    CGContextStrokePath(ctx);
}

图形上下文矩阵的操作(对上下文的路径进行的一些操作,如平移、旋转、缩放)

- (void)drawRect:(CGRect)rect {
    //获取当前的上下文.
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //画一个椭圆
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-100, -50, 200, 100)];

    //上下文的矩阵操作,就是可以上下文当中的路径进行一些形变操作.
    //平移操作
    CGContextTranslateCTM(ctx, 100, 50);
    //缩放操作
    CGContextScaleCTM(ctx, 0.5, 0.5);
    //旋转操作
    CGContextRotateCTM(ctx, M_PI_4);
   
    //注意形变操作要在添加路径之前进行.
    [[UIColor redColor]set];
    //把路径添加到上下文.
    CGContextAddPath(ctx, path.CGPath);
    //把上下文的内容渲染到View.
    CGContextFillPath(ctx);  
}
上一篇 下一篇

猜你喜欢

热点阅读