1 //重写drawRect: 2 - (void)drawRect:(CGRect)rect { 3 // 1.获得图形上下文 4 CGContextRef ctx = UIGraphicsGetCurrentContext(); 5 6 // 2.拼接图形 7 // 2.1设置一个起点 8 CGContextMoveToPoint(ctx, 10, 10); 9 10 // 2.2添加一条线段,是从(10,10)到(100,100) 11 CGContextAddLineToPoint(ctx, 100, 100); 12 13 // 2.3从上次的位置开始再添加一条线段,是从(100,100)到(150,40) 14 CGContextAddLineToPoint(ctx, 150, 40); 15 16 // 2.4最后画一条直线连接会原处,形成一个三角形 17 // CGContextAddLineToPoint(ctx, 10, 10); 18 CGContextClosePath(ctx); // 回到起点 19 20 // 3.渲染显示到view上面 21 CGContextStrokePath(ctx); 22 }2.画矩形
1 - (void)drawRect:(CGRect)rect { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 2.画四边形 6 CGContextAddRect(ctx, CGRectMake(10, 10, 80, 100)); 7 8 // 绘制空心图形 9 // CGContextStrokePath(ctx); 10 11 // 绘制实心图形 12 CGContextFillPath(ctx); 13 }3.画圆
1 - (void) drawRound { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 2.1画圆 6 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100)); 7 8 // 2.2椭圆 9 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 150, 100)); 10 11 // 渲染 12 CGContextStrokePath(ctx); 13 }4.画圆弧
1 - (void) drawArc { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 2.圆弧 6 // X轴正方向为0角度,最后一个参数1代表逆时针方向 7 CGContextAddArc(ctx, 100, 100, 50, 0, -M_PI, 1); 8 9 // 渲染 10 CGContextStrokePath(ctx); 11 }
1 // 2.圆弧 2 // X轴正方向为0角度,最后一个参数1代表逆时针方向 3 CGContextAddArc(ctx, 100, 100, 50, 0, -M_PI, 0);
5.画文字
1 - (void) drawText { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 2.画上文字 6 /** 7 * 如果使用已经过期的方法 CGContextShowText,由于CG画板是以左下角为零点,所以字会上下颠倒过来 8 */ 9 NSString *text = @"hello, 你好啊"; 10 // [text drawAtPoint:CGPointZero withAttributes:nil]; 11 12 CGRect r = CGRectMake(50, 50, 100, 100); 13 CGContextAddRect(ctx, r); 14 CGContextFillPath(ctx); 15 16 NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 17 dict[NSForegroundColorAttributeName] = [UIColor redColor]; // 前景色,就是字体颜色 18 dict[NSFontAttributeName] = [UIFont systemFontOfSize:20]; // 字体 19 [text drawInRect:r withAttributes:dict]; 20 21 // 渲染 22 CGContextStrokePath(ctx); 23 }6.画图片 (1)使用已经封装好,不用手动转换坐标的方法
1 - (void) drawImg { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 取得图片 6 UIImage *img = [UIImage imageNamed:@"M4"]; 7 8 // 画上图片 9 // [img drawAtPoint:CGPointZero]; // 原图大小,可能显示不全 10 [img drawInRect:CGRectMake(0, 0, 100, 200)]; // 填充方式默认是拉伸 11 12 // 渲染 13 CGContextStrokePath(ctx); 14 }(2)填充方式 a.drawAtPoint 默认是原图 [img drawAtPoint:CGPointZero]; // 原图大小,可能显示不全 b.drawInRect 是拉伸 [img drawInRect:CGRectMake(0, 0, 100, 200)]; // 填充方式默认是拉伸 c.drawAsPetternInRect
1 - (void) drawImg { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 取得图片 6 UIImage *img = [UIImage imageNamed:@"M4Mini"]; // 小图 7 8 // 画上图片 9 [img drawAsPatternInRect:CGRectMake(0, 0, 200, 200)]; // 重复,可以用来做花纹 10 11 // 渲染 12 CGContextStrokePath(ctx); 13 }(3)文字水印
1 - (void) drawImg { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 取得图片 6 UIImage *img = [UIImage imageNamed:@"M4"]; // 大图 7 // UIImage *img = [UIImage imageNamed:@"M4Mini"]; // 小图 8 9 // 画上图片 10 // [img drawAtPoint:CGPointZero]; // 原图大小,可能显示不全 11 [img drawInRect:CGRectMake(0, 0, 100, 200)]; // 填充方式默认是拉伸 12 // [img drawAsPatternInRect:CGRectMake(0, 0, 200, 200)]; // 重复,可以用来做花纹 13 14 // 文字 15 NSString *text = @"这是一个美女"; 16 [text drawInRect:CGRectMake(0, 0, 100, 30) withAttributes:nil]; 17 18 // 渲染 19 CGContextStrokePath(ctx); 20 }
G.画一个小黄人 利用基本的图形描绘一个简单地小黄人头像 使用弧线、直线、椭圆 H.图形上下文栈 为了在更改上下文设置后能够完全、方便地恢复原来的设置
1 - (void) contextStackDemo { 2 // 1.获得上下文 3 CGContextRef ctx = UIGraphicsGetCurrentContext(); 4 5 // 2.存储上下文 6 CGContextSaveGState(ctx); 7 8 // 3.设置上下文 9 CGContextSetLineCap(ctx, kCGLineCapRound); 10 CGContextSetLineWidth(ctx, 10); 11 [[UIColor redColor] set]; 12 13 // 4.画第一条直线 14 CGContextMoveToPoint(ctx, 10, 10); 15 CGContextAddLineToPoint(ctx, 100, 100); 16 17 // 渲染 18 CGContextStrokePath(ctx); 19 20 // 5.恢复上下文 21 CGContextRestoreGState(ctx); 22 23 // 6.第二条直线 24 CGContextMoveToPoint(ctx, 100, 10); 25 CGContextAddLineToPoint(ctx, 10, 100); 26 27 // 渲染 28 CGContextStrokePath(ctx); 29 }I.矩阵操作 裁剪 1.矩阵旋转、缩放、移动操作
1 - (void) testCTM { 2 CGContextRef ctx = UIGraphicsGetCurrentContext(); 3 4 CGContextSaveGState(ctx); 5 6 CGContextRotateCTM(ctx, M_PI_4 * 0.3); // 旋转 7 CGContextScaleCTM(ctx, 0.5, 0.5); // 缩放 8 CGContextTranslateCTM(ctx, 100, 0); // 移动 9 10 CGContextAddRect(ctx, CGRectMake(10, 10, 100, 100)); 11 CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 60, 60)); 12 13 CGContextMoveToPoint(ctx, 200, 100); 14 CGContextAddLineToPoint(ctx, 50, 200); 15 16 CGContextStrokePath(ctx); 17 18 }2.裁剪
1 - (void) testClip { 2 CGContextRef ctx = UIGraphicsGetCurrentContext(); 3 4 // 画一个圆 5 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 150, 150)); 6 7 // 裁剪 8 CGContextClip(ctx); 9 10 // 加上图片 11 UIImage *img = [UIImage imageNamed:@"a9ec8a13632762d0092abc3ca2ec08fa513dc619"]; 12 [img drawInRect:CGRectMake(0, 0, 150, 150)]; 13 14 CGContextStrokePath(ctx); 15 }J.重绘(刷帧) setNeedDisplay 1.通过一个滑块控件来控制一个圆的动态大小 (1)在storyboard中描绘一个view和一个slider (2)拖入slider的值变化事件和view到控制器,并使用自定义类为view的class (3)在自定义UIView类中实现drawRect,在适当的地方调用setNeddDisplay重绘 MyView:
1 - (void)setRadius:(CGFloat)radius { 2 _radius = radius; 3 4 // 调用重绘/刷帧方法 5 [self setNeedsDisplay]; 6 } 7 8 // 初始化控件的时候, drawRect只会调用一次 9 - (void)drawRect:(CGRect)rect { 10 CGContextRef ctx = UIGraphicsGetCurrentContext(); 11 12 CGContextAddArc(ctx, 125, 125, self.radius, M_PI * 2, 0, 1); 13 CGContextFillPath(ctx); // 实心圆 14 }ViewController:
1 @interface ViewController () 2 - (IBAction)onSlideChange:(UISlider *)sender; 3 @property (weak, nonatomic) IBOutlet MyView *circleView; 4 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 // Do any additional setup after loading the view, typically from a nib. 12 } 13 14 - (void)didReceiveMemoryWarning { 15 [super didReceiveMemoryWarning]; 16 // Dispose of any resources that can be recreated. 17 } 18 19 - (IBAction)onSlideChange:(UISlider *)sender { 20 self.circleView.radius = sender.value * 100; 21 } 22 @end可以用滑条控制圆的大小 2.下雪动画 使用定时器 Timer 使用CADisplayLink
1 - (void)awakeFromNib { 2 // 添加定时器 3 // [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; 4 5 // 刷新更快的工具 6 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)]; // 创建 7 8 // 添加到消息循环,启动 9 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 10 } 11 12 - (void)drawRect:(CGRect)rect { 13 self.snowY += 1; 14 if (self.snowY >= self.frame.size.height) { 15 self.snowY = -100; 16 } 17 UIImage *image = [UIImage imageNamed:@"M2Mini"]; 18 [image drawAtPoint:CGPointMake(100, self.snowY)]; 19 }