UI基础 - Quartz 2D 1.2:涂鸦 | - ???
画笔涂鸦
1 - 代码示例:根据数据源(坐标),绘制路径
// - DoodleView.m
1 #import "DoodleView.h" 2 @implementation DoodleView 3 4 - (void)drawRect:(CGRect)rect { 5 6 // 得到上下文:只能在两种方式种获取到:drawRect 方法中 或者 image 图片 7 CGContextRef context = UIGraphicsGetCurrentContext(); 8 CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);// 画笔颜色 9 CGContextSetLineWidth(context, 2.0);// 画笔粗细 10 11 // 搞几个坐标点 12 NSArray *pointArray = [NSArray arrayWithObjects:@[@40,@40], 13 @[@100,@30], 14 @[@100,@200], 15 @[@50,@150], 16 @[@40,@40],nil]; 17 18 for (int i = 0; i < (int)pointArray.count -1; i++) { 19 20 CGContextMoveToPoint(context, [[[pointArray objectAtIndex:i] firstObject] floatValue], [[[pointArray objectAtIndex:i] lastObject] floatValue]); 21 CGContextAddLineToPoint(context, [[[pointArray objectAtIndex:i+1] firstObject] floatValue], [[[pointArray objectAtIndex:i+1] lastObject] floatValue]); 22 } 23 24 CGContextStrokePath(context); 25 } 26 27 @end
// - ViewController.m
1 #import "ViewController.h" 2 #import "DoodleView.h" 3 @implementation ViewController 4 5 - (void)viewDidLoad { 6 [super viewDidLoad]; 7 8 DoodleView *doodleView = [[DoodleView alloc] initWithFrame:self.view.bounds]; 9 doodleView.backgroundColor = [UIColor cyanColor]; 10 [self.view addSubview:doodleView]; 11 12 } 13 14 @end
运行效果
2 - 代码示例:涂鸦
// - DoodleView.m
1 #import "DoodleView.h" 2 @interface DoodleView () 3 4 @property(nonatomic,strong)NSMutableArray *lineArray;// 存放所有单个路径 5 @end 6 7 @implementation DoodleView 8 9 - (instancetype)initWithFrame:(CGRect)frame{ 10 self = [super initWithFrame:frame]; 11 if (self) { 12 13 self.lineArray = [NSMutableArray array]; 14 15 // 取消按钮 16 UIButton *cancelBT = [UIButton buttonWithType:UIButtonTypeCustom]; 17 cancelBT.frame = CGRectMake((self.frame.size.width-120)*0.5, 510, 120, 30); 18 [cancelBT setTitle:@"cancel" forState:UIControlStateNormal]; 19 cancelBT.layer.cornerRadius = 10; 20 cancelBT.backgroundColor = [UIColor redColor]; 21 [self addSubview:cancelBT]; 22 [cancelBT addTarget:self action:@selector(makeCancel) forControlEvents:UIControlEventTouchUpInside]; 23 24 } 25 return self; 26 } 27 28 // 撤回上次的绘图操作 29 -(void)makeCancel{ 30 31 [self.lineArray removeLastObject]; 32 [self setNeedsDisplay]; 33 } 34 35 - (void)drawRect:(CGRect)rect { 36 37 CGContextRef context = UIGraphicsGetCurrentContext(); 38 CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);// 画笔颜色 39 CGContextSetLineWidth(context, 2.0); 40 41 // 首先遍历大数组 self.lineArray,获取每一条线( 所有点 )的小数组 ponitArray 42 // 再次遍历小数组中所有的点,进行绘制 43 for (int i = 0 ; i< self.lineArray.count; i ++) { 44 45 NSMutableArray *ponitArray = [self.lineArray objectAtIndex:i]; 46 47 for (int j = 0; j < (int)ponitArray.count - 1; j++) { 48 NSValue *firstValue = [ponitArray objectAtIndex:j]; 49 NSValue *secondValue = [ponitArray objectAtIndex:j+1]; 50 51 CGPoint firstPoint = [firstValue CGPointValue]; 52 CGPoint secondPoint = [secondValue CGPointValue]; 53 54 CGContextMoveToPoint(context, firstPoint.x, firstPoint.y); 55 CGContextAddLineToPoint(context, secondPoint.x, secondPoint.y); 56 } 57 } 58 59 CGContextStrokePath(context);// 渲染 60 } 61 62 // 开始绘制:现在并没有拿到路径上具体的点,所以此时应该先用一个数组保存一条路径 63 // 每一次调用都应该是创建一个新的路径( 新的 linePathArray ),然后添加到保存所有路径的数组中( self.lineArray) 64 // 最后调用 setNeedsDisplay 方法,绘制路径 65 -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event{ 66 67 UITouch *touch = [touches anyObject]; 68 CGPoint currentPoint = [touch locationInView:self]; 69 70 //linePathArray( 保存了一条 line ) 71 NSMutableArray *linePathArray = [NSMutableArray array]; 72 NSValue *ponitValue = [NSValue valueWithCGPoint:currentPoint]; 73 [linePathArray addObject:ponitValue]; 74 [self.lineArray addObject:linePathArray]; 75 [self setNeedsDisplay]; 76 } 77 78 // 给最新添加的那个路径添加点,所以应当找到数组中最后一个路径,然后给这个路径添加 point 79 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 80 81 UITouch *touch = [touches anyObject]; 82 CGPoint currentPoint = [touch locationInView:self]; 83 NSMutableArray *lastLineArr = [self.lineArray lastObject]; 84 NSValue *ponitValue = [NSValue valueWithCGPoint:currentPoint]; 85 [lastLineArr addObject:ponitValue]; 86 [self setNeedsDisplay]; 87 } 88 89 // 同 touchesMoved 90 -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 91 UITouch *touch = [touches anyObject]; 92 CGPoint currentPoint = [touch locationInView:self]; 93 NSMutableArray *lastLineArr = [self.lineArray lastObject]; 94 NSValue *ponitValue = [NSValue valueWithCGPoint:currentPoint]; 95 [lastLineArr addObject:ponitValue]; 96 [self setNeedsDisplay]; 97 } 98 99 @end
用此方式涂鸦越频繁,会造成设备明显卡顿,如何解决 ?
// - ViewController.m
1 #import "ViewController.h" 2 #import "DoodleView.h" 3 @implementation ViewController 4 5 - (void)viewDidLoad { 6 [super viewDidLoad]; 7 DoodleView *doodleView = [[DoodleView alloc] initWithFrame:self.view.bounds]; 8 doodleView.backgroundColor = [UIColor whiteColor]; 9 [self.view addSubview:doodleView]; 10 } 11 12 @end
运行效果