iOS quartz2D 的从零到一学习使用

什么是Quartz2D?二维的绘图引擎
什么是二维?平面
什么是引擎?经包装的函数库,方便开发者使用。也就是说苹果帮我们封装了一套绘图的函数库
同时支持iOS和Mac系统什么意思?用Quartz2D写的同一份代码,既可以运行在iphone上又可以运行在mac上,可以跨平台开发。
开发中比较常用的是截屏/裁剪/自定义UI控件。
Quartz2D在iOS开发中的价值就是自定义UI控件。


使用图形上下文画图,要遵循一下四个步骤
1.获取图像上下文
2.创建路径
3.将路径添加到图形上下文(add)
4.渲染图像上下文(fill,stroke)

以下方法请在UIView的drawRect方法中调用~

一.绘制一条直线的方法

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - 直接使用图形上下文画图  
  2. - (void)oneMethod  
  3. {  
  4.     //1.获取图形上下文,目前我们现在使用的都是UIGraphics开头,CoreGraphics,项目简称CG  
  5.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
  6.       
  7.     //2.描述路径  
  8.     //2.1 创建路径  
  9.     CGContextMoveToPoint(ctx, 1050);  
  10.     //2.2 添加线到一个点  
  11.     CGContextAddLineToPoint(ctx, 10,100);  
  12.       
  13.     //3.完成路线  
  14.     CGContextStrokePath(ctx);  
  15.   
  16. }  
  17. #pragma mark - 图形上下文 + CGPathRef画线  
  18. - (void)twoMethod  
  19. {  
  20.     //1.获取图形上下文  
  21.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
  22.       
  23.     //2.使用path画线  
  24.     CGMutablePathRef path = CGPathCreateMutable();  
  25.       
  26.     //3.添加点  
  27.     CGPathMoveToPoint(path, NULL2050);  
  28.     CGPathAddLineToPoint(path, NULL20100);  
  29.       
  30.     //4.将path添加到图形上下文  
  31.     CGContextAddPath(ctx, path);  
  32.       
  33.     //5.渲染上下文  
  34.     CGContextStrokePath(ctx);  
  35. }  
  36. #pragma mark - 贝塞尔曲线  
  37. - (void)threeMethod  
  38. {  
  39.     //1.创建路径  
  40.     UIBezierPath *path = [UIBezierPath bezierPath];  
  41.       
  42.     //2.画线  
  43.     [path moveToPoint:CGPointMake(3050)];  
  44.     [path addLineToPoint:CGPointMake(30100)];  
  45.       
  46.     //3.渲染  
  47.     [path stroke];  
  48. }  
  49. #pragma mark - 图形上下文 + 贝塞尔曲线  
  50. - (void)fourMethod  
  51. {  
  52.     //1.获得图形上下文  
  53.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
  54.       
  55.     //2.创建路径  
  56.     UIBezierPath *path = [UIBezierPath bezierPath];  
  57.       
  58.     //3.画线  
  59.     [path moveToPoint:CGPointMake(4050)];  
  60.     [path addLineToPoint:CGPointMake(40100)];  
  61.       
  62.     //4.将path添加到上下文  
  63.     CGContextAddPath(ctx, path.CGPath);  
  64.       
  65.     //5.渲染  
  66.     CGContextStrokePath(ctx);  
  67. }  

二.画两个相交的线,并且设置属性

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - 画两个相交的线,并设置属性  
  2. - (void)drawTwoLineCrossSetAttribute  
  3. {  
  4.     //1.获取图形上下文  
  5.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
  6.       
  7.     //2.将绘制路径,并且将其添加到图形上下文  
  8.     CGContextMoveToPoint(ctx, 12345);  
  9.     CGContextAddLineToPoint(ctx, 4580);  
  10.       
  11.     //3.添加另一条线  
  12.     CGContextAddLineToPoint(ctx, 223159);  
  13.       
  14.     //设置颜色  
  15.     [[UIColor greenColor] set];  
  16.     //设置线的宽度  
  17.     CGContextSetLineWidth(ctx, 10);  
  18.     //设置链接外的链接类型  
  19.     CGContextSetLineJoin(ctx, kCGLineJoinRound);  
  20.     //设置线的头部方式  
  21.     CGContextSetLineCap(ctx, kCGLineCapRound);  
  22.       
  23.     //4.渲染  
  24.     CGContextStrokePath(ctx);  
  25. }  


画出了两条有链接的线,其中设置颜色的时候,是区分 设置线的颜色 ,和 设置图片的颜色 的,可以设置他们各自的属性(但是经常设置错误),懒得去区分并且保证不会设置错误,建议设置 [[UIColor greenColor] set] 就不用考虑实线还是填充图形了。还有, CGContextSetLineJoin 是设置连接处的样式,是枚举, CGContextSetLineCap 是设置线的顶部的样式,也是枚举。
注意:设置各种属性的时候,一定要记住在渲染之前,否则无效

三.绘制两条不相交的线,并且设置各自属性


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - 画两个不相交的线,并且设置各自属性  
  2. - (void)drawTwoLineNoCrossSetAttribute  
  3. {  
  4.     //1.创建贝塞尔曲线路径  
  5.     UIBezierPath *path = [UIBezierPath bezierPath];  
  6.       
  7.     //2.绘制路径  
  8.     [path moveToPoint:CGPointMake(1249)];  
  9.     [path addLineToPoint:CGPointMake(6834)];  
  10.     [[UIColor redColor] set];  
  11.     [path setLineWidth:5];  
  12.     //3.渲染  
  13.     [path stroke];  
  14.       
  15.     //绘制第二条路径  
  16.     UIBezierPath *path2 = [UIBezierPath bezierPath];  
  17.     [path2 moveToPoint:CGPointMake(145167)];  
  18.     [path2 addLineToPoint:CGPointMake(9834)];  
  19.     [[UIColor greenColor] set];  
  20.     [path2 setLineWidth:10];  
  21.     [path2 setLineCapStyle:kCGLineCapRound];  
  22.     [path2 stroke];  
  23.       
  24. }  

使用贝塞尔曲线画图的好处在于,1.每一个贝塞尔底层都有一个图形上线文,如果是用CGContextMoveToPoint画图,实际上就是一个图形上下文,不好去控制,所以建议没多条线可以使用贝塞尔曲线或者说使用底层的CGMutablePathRef画线,比较靠谱。


四.绘制曲线


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - 绘制曲线  
  2. - (void)drawQuadCurve  
  3. {  
  4.     //1.获得图形上下文  
  5.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
  6.       
  7.     //2.设置起点  
  8.     CGContextMoveToPoint(ctx, 1050);  
  9.       
  10.     /** 
  11.      *  添加曲线的五个参数 
  12.      * 
  13.      *  @param c#>   图形上下文 
  14.      *  @param cpx#> 将来要突出的x值 
  15.      *  @param cpy#> 要突出的y值 
  16.      *  @param x#>   曲线结束时的x 
  17.      *  @param y#>   曲线结束时的y 
  18.      */  
  19.       
  20.     CGContextAddQuadCurveToPoint(ctx, 16030031050);  
  21.       
  22.     //设置颜色  
  23.     [[UIColor redColor] set];  
  24.     //设置宽度  
  25.     CGContextSetLineWidth(ctx, 5);  
  26.       
  27.     //3.渲染图层  
  28.     CGContextStrokePath(ctx);  
  29. }  


五.绘制带有圆角边框的正方形


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - 绘制一个带有圆角边框的正方形  
  2. - (void)drawRoundSquare  
  3. {  
  4.     //绘制一个空心的圆角矩形  
  5.     //1.创建路径 贝塞尔曲线  
  6.     UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(105010040) cornerRadius:5];  
  7.     //设置颜色  
  8.     [[UIColor redColor] set];  
  9.     //2.渲染  
  10.     [path stroke];  
  11.       
  12.     //绘制一个实心的圆角正方形  
  13.     //1.创建路径 贝塞尔曲线  
  14.     UIBezierPath *path2 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(10140100100) cornerRadius:5];  
  15.     //设置颜色  
  16.     [[UIColor orangeColor] set];  
  17.     //2.渲染  
  18.     [path2 fill];  
  19.       
  20.     //绘制一个实心的圆  
  21.     //1.创建路径 贝塞尔曲线  
  22.     UIBezierPath *path3 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(10290100100) cornerRadius:50];  
  23.     //设置颜色  
  24.     [[UIColor blueColor] set];  
  25.     //2.渲染  
  26.     [path3 fill];  
  27.   
  28. }  


  • 1.stroke设置边框的颜色,fill填充内部的颜色
  • 2.fill并不是随意使用的,必须是封闭的图形。
  • 3.可以通过设置圆角是正方形的高度,生成一个原形,但不是最规范绘制原形的方法,不过也可以使用。

六.绘制一个弧度曲线


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - 绘制一个弧度曲线  
  2. - (void)drawCurve  
  3. {  
  4.     /** 
  5.      *  绘制弧度曲线 
  6.      * 
  7.      *  @param ArcCenter 曲线中心 
  8.      *  @param radius       半径 
  9.      *  @param startAngle 开始的弧度 
  10.      *  @param endAngle 结束的弧度 
  11.      *  @param clockwise YES顺时针,NO逆时针 
  12.      */  
  13.       
  14.     //绘制一条半圆曲线  
  15.     //1.创建路径 贝塞尔曲线  
  16.     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150150) radius:50 startAngle:0 endAngle:M_PI clockwise:YES];  
  17.     [[UIColor redColor] set];  
  18.     [path setLineWidth:10];  
  19.     [path setLineCapStyle:(kCGLineCapRound)];  
  20.     //2.渲染  
  21.     [path stroke];  
  22.       
  23.     //绘制一条3/4圆曲线  
  24.     //1.创建路径 贝塞尔曲线  
  25.     UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150350) radius:50 startAngle:0 endAngle:270/360.0*(M_PI * 2) clockwise:YES];  
  26.     [[UIColor yellowColor] set];  
  27.     [path2 setLineWidth:10];  
  28.     [path2 setLineCapStyle:(kCGLineCapRound)];  
  29.     //2.渲染  
  30.     [path2 stroke];  
  31.       
  32.     //绘制一个圆形曲线  
  33.     //1.创建路径 贝塞尔曲线  
  34.     UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150550) radius:50 startAngle:0 endAngle:(M_PI * 2) clockwise:YES];  
  35.     [[UIColor blueColor] set];  
  36.     [path3 setLineWidth:10];  
  37.     [path3 setLineCapStyle:(kCGLineCapRound)];  
  38.     //2.渲染  
  39.     [path3 stroke];  
  40.       
  41. }  


1.M_PI是180度.M_PI_2是90°
2.这里的角度都是弧度制度,如果我们需要15°,可以用15°/180°*π得到。
3.clockwise这个是顺时针,如果穿1,就是顺时针,穿0,是逆时针

七.绘制一个一个扇形

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">#pragma mark - 绘制扇形  
  2. - (void)drawFanShaped  
  3. {  
  4.     //1.获取图形上下文  
  5.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
  6.     //绘制曲线  
  7.     CGFloat centerX = 100;  
  8.     CGFloat centerY = 100;  
  9.     CGFloat radius = 50;  
  10.     //2.添加一根线  
  11.     CGContextMoveToPoint(ctx, centerX, centerY);  
  12.     CGContextAddArc(ctx, centerX, centerY, radius, M_PI, (230 / 360.0)*(M_PI * 2), NO);  
  13.       
  14.     //3.关闭线段  
  15.     CGContextClosePath(ctx);  
  16.     //4.渲染  
  17.     CGContextFillPath(ctx);  
  18.       
  19. }</span>  
1.线添加一个点CGContextMoveToPoint
2.添加一个圆弧CGContextAddArc
3.闭合绘图CGContextClosePath
4.给路径设置颜色CGContextStrokePath,或者给图形内部设置颜色CGContextFillPath
5.使用贝塞尔曲线,也要设置闭合路径CGContextClosePath



学有所成,来个小练习~

八.简单下载进度的demo

自定义一个View
CustomProgressView.h
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @interface CustomProgressView : UIView  
  2. @property (nonatomic,assign) CGFloat progressValue;  
  3. @end  

CustomProgressView.m
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @implementation CustomProgressView  
  2. - (void)setProgressValue:(CGFloat)progressValue  
  3. {  
  4.     _progressValue = progressValue;  
  5.     [self setNeedsDisplay];  
  6. }  
  7. -(void)drawRect:(CGRect)rect  
  8. {  
  9.     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.center radius:100 startAngle:-M_PI_2 endAngle:(_progressValue / 100.0) *(22 * M_PI) - M_PI_2 clockwise:YES];  
  10.     [[UIColor redColor] set];  
  11.     [path setLineWidth:10];  
  12.     [path setLineCapStyle:(kCGLineCapRound)];  
  13.     [path stroke];  
  14. }  
  15.   
  16. @end  
ViewController.m
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @interface ViewController ()  
  2. @property (nonatomic,retainUISlider *slider;  
  3. @property (nonatomic,retainCustomProgressView *progressView;  
  4. @property (nonatomic,retainUILabel *label;  
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad {  
  10.     [super viewDidLoad];  
  11.     self.progressView = [[CustomProgressView alloc]initWithFrame:CGRectMake(00self.view.frame.size.widthself.view.frame.size.width)];  
  12.     self.progressView.backgroundColor = [UIColor whiteColor];  
  13.       
  14.     self.label = [[UILabel alloc]initWithFrame:CGRectMake(008050)];  
  15.     self.label.center = self.progressView.center;  
  16.     self.label.textAlignment = NSTextAlignmentCenter;  
  17.     [self.progressView addSubview:self.label];  
  18.       
  19.     [self.view addSubview:self.progressView];  
  20.       
  21.       
  22.     self.slider = [[UISlider alloc]initWithFrame:CGRectMake(10500self.view.frame.size.width - 2050)];  
  23.     self.slider.minimumValue = 0;  
  24.     self.slider.maximumValue = 100;  
  25.     [self.slider addTarget:self action:@selector(changeValue:) forControlEvents:(UIControlEventValueChanged)];  
  26.     [self.view addSubview:self.slider];  
  27. }  
  28. - (void)changeValue:(UISlider *)sender  
  29. {  
  30.     self.progressView.progressValue = sender.value;  
  31.     self.label.text = [NSString stringWithFormat:@"%.f%%",sender.value];  
  32. }  
  33. - (void)didReceiveMemoryWarning {  
  34.     [super didReceiveMemoryWarning];  
  35.     // Dispose of any resources that can be recreated.  
  36. }  
  37.   
  38. @end  


想调用这个方法drawRect:(CGRect)rect,必须要使用setNeedsDisplay,其他的无效。

九.饼状图

PieView.m

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @interface PieView ()  
  2. @property (nonatomic,retainNSArray *nums;  
  3. @property (nonatomic,assign) NSInteger total;  
  4. @end  
  5. @implementation PieView  
  6. - (NSInteger)total  
  7. {  
  8.     if (_total == 0) {  
  9.         for (int i = 0; i < self.nums.count ; i ++) {  
  10.             _total += [self.nums[i] integerValue];  
  11.         }  
  12.     }  
  13.     return _total;  
  14. }  
  15. - (NSArray *)nums  
  16. {  
  17.     if (!_nums) {  
  18.         self.nums = @[@"10",@"20",@"30",@"40"];  
  19.     }  
  20.     return _nums;  
  21. }  
  22. - (void)drawRect:(CGRect)rect  
  23. {  
  24.     //绘制一个饼图  
  25.     CGFloat radius = 150;  
  26.     CGFloat startA = 0;  
  27.     CGFloat endA = 0;  
  28.       
  29.     for (int i = 0; i < self.nums.count; i++) {  
  30.         NSNumber *num = self.nums[i];  
  31.         startA = endA;  
  32.         endA = startA + [num floatValue]/self.total * (22 * M_PI);  
  33.         UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.center radius:radius startAngle:startA endAngle:endA clockwise:YES];  
  34.         [path addLineToPoint:self.center];  
  35.           
  36.         CGFloat randRed = arc4random_uniform(256)/255.0;  
  37.         CGFloat randGreen = arc4random_uniform(256)/255.0;  
  38.         CGFloat randBlue = arc4random_uniform(256)/255.0;  
  39.         UIColor *randomColor = [UIColor colorWithRed:randRed green:randGreen blue:randBlue alpha:1];  
  40.         [randomColor set];  
  41.           
  42.         [path fill];  
  43.     }  
  44. }  
  45.   
  46. @end  

ViewController.m
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. PieView *pie = [[PieView alloc]initWithFrame:[UIScreen mainScreen].bounds];  
  2.    pie.backgroundColor = [UIColor whiteColor];  
  3.    [self.view addSubview:pie];  




十.柱状图


BarChartView.h
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @interface BarChartView()  
  2. @property (nonatomic,retainNSArray *nums;  
  3. @end  
  4. @implementation BarChartView  
  5. - (NSArray *)nums  
  6. {  
  7.     if (!_nums) {  
  8.         self.nums = @[@"10",@"20",@"30",@"40",@"50",@"60",@"70",@"80"];  
  9.     }  
  10.     return _nums;  
  11. }  
  12. - (void)drawRect:(CGRect)rect  
  13. {  
  14.     //1.获取图形上下文  
  15.     CGContextRef ctz = UIGraphicsGetCurrentContext();  
  16.     //2.绘制图像  
  17.     //设置间距  
  18.     CGFloat margin = 30;  
  19.     //当柱状图的数量多于5的时候缩小它们的间距  
  20.     if (self.nums.count > 5) {  
  21.         margin = 10;  
  22.     }  
  23.     //柱状图的宽度 = ( view的宽度 - 间隔的总宽度 )/ 柱状图的个数  
  24.     CGFloat width = (rect.size.width - (self.nums.count + 1) *margin) / self.nums.count;  
  25.     for (int i = 0; i < self.nums.count; i++) {  
  26.           
  27.         //求出 每一个数字所占的比例  
  28.         CGFloat num = [self.nums[i] floatValue]/100;  
  29.         //起点位置  
  30.         CGFloat x = margin + (width + margin) * i ;  
  31.         CGFloat y = rect.size.height * (1 - num);  
  32.         CGFloat height = rect.size.height * num;  
  33.           
  34.         CGRect rectA = CGRectMake(x, y, width, height);  
  35.         CGContextAddRect(ctz, rectA);  
  36.           
  37.         CGFloat randRed = arc4random_uniform(256)/255.0;  
  38.         CGFloat randGreen = arc4random_uniform(256)/255.0;  
  39.         CGFloat randBlue = arc4random_uniform(256)/255.0;  
  40.         UIColor *randomColor = [UIColor colorWithRed:randRed green:randGreen blue:randBlue alpha:1];  
  41.           
  42.         [randomColor set];  
  43.         //渲染  
  44.         CGContextFillPath(ctz);  
  45.          
  46.     }  
  47. }  
  48. /* 
  49. // Only override drawRect: if you perform custom drawing. 
  50. // An empty implementation adversely affects performance during animation. 
  51. - (void)drawRect:(CGRect)rect { 
  52.     // Drawing code 
  53. } 
  54. */  
  55.   
  56. @end  

ViewController.m
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. BarChartView *view = [[BarChartView alloc]initWithFrame:[UIScreen mainScreen].bounds];  
  2.    view.backgroundColor = [UIColor whiteColor];  
  3.    [self.view addSubview:view];  



十一.绘制图片

绘制文字和图片的时候,是不用去获取图像上下文的

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. -(void)drawRect:(CGRect)rect  
  2. {  
  3.     //剪切图片,超出的图片位置都要剪切掉!必须要在绘制之前写,否则无效  
  4. //    UIRectClip(CGRectMake(0, 0, 100, 50));  
  5.       
  6.     UIImage *image = [UIImage imageNamed:@"image"];  
  7.       
  8.     //独立  
  9.     //在什么范围内(原图大小)  
  10.     [image drawInRect:rect];  
  11.       
  12.     //在哪个位置开始画  
  13.     [image drawAtPoint:CGPointMake(1010)];  
  14.       
  15.     //平铺  
  16.     [image drawAsPatternInRect:rect];  
  17. }  


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [image drawInRect:rect]; //拉伸效果  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [image drawAtPoint:CGPointMake(1010)];//适应效果  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [image drawAsPatternInRect:rect];//平铺效果  

十二.绘制富文本


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)drawRect:(CGRect)rect  
  2. {  
  3.     NSString *str = @"不管开心与否\n每天都要努力生活\n爱自己\n爱家人";  
  4.     //设置文字的属性  
  5.     NSMutableDictionary * paras = [NSMutableDictionary dictionary];  
  6.     //设置字体大小  
  7.     paras[NSFontAttributeName] = [UIFont systemFontOfSize:40];  
  8.     //设置字体颜色  
  9.     paras[NSForegroundColorAttributeName] = [UIColor blackColor];  
  10.     //设置镂空渲染颜色  
  11.     paras[NSStrokeColorAttributeName] = [UIColor orangeColor];  
  12.     //设置镂空渲染宽度  
  13.     paras[NSStrokeWidthAttributeName] = @3;  
  14.       
  15.     //创建阴影对象  
  16.     NSShadow *shodow = [[NSShadow alloc] init];  
  17.     //阴影颜色  
  18.     shodow.shadowColor = [UIColor yellowColor];  
  19.     //阴影偏移量  
  20.     shodow.shadowOffset = CGSizeMake(56);  
  21.     //阴影的模糊半径  
  22.     shodow.shadowBlurRadius = 4;  
  23.     //苹果的富文本就是这样搞出来的  
  24.     paras[NSShadowAttributeName]  = shodow;  
  25.     [str drawAtPoint:CGPointZero withAttributes:paras];  
  26. }  



十三.雪花飘动



雪花动画
//只有在drawRect方法中才能拿到图形上下文,才可以画图
- (void)drawRect:(CGRect)rect {
    //设置下雪的动画
    UIImage *image = [UIImage imageNamed:@"snow"];
    _snowY += 10;

    [image drawAtPoint:CGPointMake(0, _snowY)];
    if (_snowY >= rect.size.height) {
        _snowY = 0;
    }
}
// 如果在绘图的时候需要用到定时器,通常使用CADisplayLink
// NSTimer很少用于绘图,因为调度优先级比较低,并不会准时调用
- (void)awakeFromNib
{
    // 创建定时器
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];

    // 添加主运行循环
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
// CADisplayLink:每次屏幕刷新的时候就会调用,屏幕一般一秒刷新60次
- (void)timeChange{
    [self setNeedsDisplay];
}

1.本质就是调用drawRect方法,一直刷新雪花的y值
2.每一次调用drawRect,都创建大量的对象,有人说可能性能不好,不过你可能多虑了,没吃都是在内存加载,不会创建新的UIImage

十四.图形上下文栈

我自己详细的介绍了一下,上下文栈,可以看一下~
图形上下文详解

十五.图形上下文矩阵

到底是个啥?
就是图形上下文画出的东西永远是方方正正的,你要是想画个偏离的矩形,按照过去的方法画不出来,只能使用矩阵的方式。分别有偏移,缩放,旋转


正常尺寸的椭圆

x,y各自平移10px后的椭圆

旋转后的椭圆

缩放后的椭圆
- (void)drawRect:(CGRect)rect {
    //图形上下文矩阵
    //1.画一个椭圆
    CGContextRef ctx = UIGraphicsGetCurrentContext();
//    CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 100, 100));
    CGPathRef path = CGPathCreateWithEllipseInRect(CGRectMake(0, 0, 200, 100),nil);
    [[UIColor redColor] set];
    //1.偏移
//    CGContextTranslateCTM(ctx, 10, 10);
   //2.旋转
//    CGContextRotateCTM(ctx, M_PI_4);
    //3.缩放
    CGContextScaleCTM(ctx, 0.25, 2);
    CGContextAddPath(ctx, path);
    CGContextFillPath(ctx);
}

1.绘制变化的图形的步骤

  • 先绘制path
  • 设置图形上下文矩阵
  • 将path添加到图形上下文(这一步很重要,一定按照步骤来)
  • 渲染

2.绘图的时候,我们要使用底层的 CGPathRef,或者贝塞尔,然后 CGContextRef+path的方式。
如不这样,我注释的CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 100, 100))方法,这个方法中已经先去添加了path到图形上下文,即使我们在去添加图形上下文矩阵,也是无效
3.可以和图形上下文栈一起使用,给特定的一些图案设置一些属性,还有一些不会受到影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值