UI进阶--Quartz2D和触摸事件的简单使用:简易涂鸦板

需求:实现一个简易的涂鸦板应用,使用鼠标在涂鸦板内拖动即可进行涂鸦,点击保存按钮,可以把完成的涂鸦保存,点击回退按钮可以向后退回一步,点击清空可以让涂鸦板清空。

实现步骤:

1、布局storyboard,连线各按钮以及涂鸦板;

2、监听触摸事件,主要为touchesBegan:和touchesMoved:;

3、获取移动的路径并添加到 UIBezierPath 对象;

4、渲染;

示例文件结构:

 

具体实现代码:

 1 //
 2 //  Scrawl.h
 3 //  1-04-Scrawl
 4 //
 5 //  Created by xiaomoge on 15/1/4.
 6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface Scrawl : UIView
12 /*
13  涂鸦线条的宽度
14  */
15 @property (nonatomic,assign) CGFloat linsWidth;
16 /*
17  回退
18  */
19 - (void)back;
20 /*
21  清屏
22  */
23 - (void)clear;
24 @end

 

 1 //
 2 //  Scrawl.m
 3 //  1-04-Scrawl
 4 //
 5 //  Created by xiaomoge on 15/1/4.
 6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
 7 //
 8 
 9 #import "Scrawl.h"
10 @interface Scrawl ()
11 /*
12  存储所有线的路径的数组
13  */
14 @property (nonatomic,strong) NSMutableArray *linsPath;
15 @end
16 @implementation Scrawl
17 #pragma mark - 懒加载
18 - (NSMutableArray *)linsPath {
19     if (!_linsPath) {
20         _linsPath = [NSMutableArray array];
21     }
22     return _linsPath;
23 }
24 - (void)drawRect:(CGRect)rect {
25     //获得当前数组中的总数
26     NSInteger count = self.linsPath.count;
27     for (NSInteger i = 0; i < count; i ++) {
28         //取得一个path对象
29         UIBezierPath *path = self.linsPath[i];
30         //设置线宽
31         path.lineWidth = self.linsWidth;
32         //设置线的首尾样式
33         path.lineCapStyle = kCGLineCapRound;
34         //设置线的连接样式
35         path.lineJoinStyle = kCGLineJoinRound;
36         //渲染
37         [path stroke];
38     }
39 }
40 //开始触摸事件
41 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
42     //取得当前触摸点的位置
43     UITouch *touch = [touches anyObject];
44     CGPoint point = [touch locationInView:touch.view];
45     //创建一个path对象,注意这里是[UIBezierPath bezierPath]
46     UIBezierPath *path = [UIBezierPath bezierPath];
47     //创建path对象的起点位置
48     [path moveToPoint:point];
49     //添加到线的路径数组中
50     [self.linsPath addObject:path];
51 }
52 //移动触摸事件
53 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
54     //取得当前触摸点的位置
55     UITouch *touch = [touches anyObject];
56     CGPoint point = [touch locationInView:touch.view];
57     //创建一个path对象,为线的路径当前的点
58     UIBezierPath *path = [self.linsPath lastObject];
59     //设置path对象的结束点
60     [path addLineToPoint:point];
61     //重绘
62     [self setNeedsDisplay];
63 }
64 //回退事件
65 - (void)back {
66     //回退其实就是把最后的一条线给清除
67     [self.linsPath removeLastObject];
68     //然后重绘
69     [self setNeedsDisplay];
70 }
71 - (void)clear {
72     //回退其实就是把所有的线给清除掉
73     [self.linsPath removeAllObjects];
74     //然后重绘
75     [self setNeedsDisplay];
76 }
77 @end

 

 1 //
 2 //  ViewController.m
 3 //  1-04-Scrawl
 4 //
 5 //  Created by xiaomoge on 15/1/4.
 6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
 7 //
 8 
 9 #import "ViewController.h"
10 #import "Scrawl.h"
11 @interface ViewController ()
12 @property (weak, nonatomic) IBOutlet Scrawl *scrawlView;
13 
14 @end
15 
16 @implementation ViewController
17 
18 - (void)viewDidLoad {
19     [super viewDidLoad];
20     self.scrawlView.linsWidth = 3;
21 }
22 - (IBAction)backClick {
23     [self.scrawlView back];
24 }
25 - (IBAction)clearClick {
26     [self.scrawlView clear];
27 }
28 - (IBAction)saveClick {
29     //开启位图上下文
30     UIGraphicsBeginImageContext(self.scrawlView.frame.size);
31     //渲染
32     [self.scrawlView.layer renderInContext:UIGraphicsGetCurrentContext()];
33     //获取当前位图上下文里的图片
34     UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
35     //结束位图上下文的编辑
36     UIGraphicsEndImageContext();
37     //把图片转为NSData
38     NSData *data = UIImagePNGRepresentation(img);
39     //保存
40     [data writeToFile:@"/Users/xiaobao/Desktop/scrawl.png" atomically:YES];
41     //注意,这里其实也可以把这个保存图片抽取成一个方法,然后调用即可。
42 }
43 @end

 

最后的效果(点击保存按钮保存下来的整个涂鸦板):

posted @ 2015-01-04 20:21  小莫哥  阅读(266)  评论(0编辑  收藏  举报