一、直接上图
二、设计说明
1、UIView继承自UIResponder,UIResponder能响应所有的事件与用户进行交互,如:触摸事件(单点/多点触控)、加速事件(重力感应)、远程事件(耳机播放/暂停/下一曲)
2、触摸事件主要涉及以下4个方法
// 开始触屏时调用,只调用一次
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
// 屏幕上移动时调用,反复调用且频率较高
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
// 离开屏幕时调用,只调用一次
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
// 中断时调用,如被来电中断
– (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
3、结合上述相关方法,使用Quartz2D绘制图形到当前视图
4、将图形保存到本地相册
三、关键代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | #import "SAView.h" @implementation SAView #pragma mark - 初始化 - (NSMutableArray *)paths { if (_paths == nil) { _paths = [NSMutableArray array]; } return _paths; } // 图层渲染方法,每调用setNeedsDisplay方法都会调用此方法 - (void)drawRect:(CGRect)rect { for (UIBezierPath *path in self.paths) { [path stroke]; } } #pragma mark - 触摸事件处理 // 开始涂鸦(以每一笔为基本单位),接触屏幕时调用一次 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"touchesBegan"); // 创建一个贝赛尔曲线对象,设置相关属性(圆角线条、线条粗细) UIBezierPath *path = [UIBezierPath bezierPath]; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; path.lineWidth = 5; // 通过touch事件获取位置变化传入给贝赛尔曲线 CGPoint point = [[touches anyObject] locationInView:self]; [path moveToPoint:point]; // 将该曲线对象加入到数组 [self.paths addObject:path]; // 刷新图层 [self setNeedsDisplay]; } // 移动手指,手指移动时会反复调用,频率较高 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"touchesMoved"); /* 获取当前画笔跟随触摸移动继续绘制 * 该方法调用频率非常高,一点点移动都会调用多次 * 所以画出的多条折线视觉上是连续的 */ UIBezierPath *path = [self.paths lastObject]; CGPoint point = [[touches anyObject] locationInView:self]; [path addLineToPoint:point]; // 刷新图层 [self setNeedsDisplay]; } // 结束触摸,即手指离开时调用一次 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"touchesEnded"); [self touchesMoved:touches withEvent:event]; } #pragma mark - 按钮事件处理 // 回退,即移除上一个画笔对象 - (IBAction)back:(id)sender { [self.paths removeLastObject]; [self setNeedsDisplay]; } // 清除,移除所有画笔对象 - (IBAction)clean:(id)sender { [self.paths removeAllObjects]; [self setNeedsDisplay]; } // 保存图片到本地相册 - (IBAction)save:(id)sender { // 开启图片上下文 UIGraphicsBeginImageContext(self.frame.size); // 将当前view上内存渲染到当前上下文 [self.layer renderInContext:UIGraphicsGetCurrentContext()]; // 将当前上下文内容转换为图片对象 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 关闭图片上下文 UIGraphicsEndImageContext(); // 将图片保存到本地相册 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); } @end |
四、Demo下载:UITouch