- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
// 定义了一个线数组,来存储所有的线
self.lineArray = [[NSMutableArray alloc] initWithCapacity:1];
// 设置一个清除按钮
UIButton *clear = [UIButton buttonWithType:UIButtonTypeSystem];
clear.frame = CGRectMake(frame.size.width-100, frame.size.height-100, 100, 100);
[clear setTitle:@"清除" forState:UIControlStateNormal];
[clear addTarget:self action:@selector(clearScreen) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:clear];
}
return self;
}
- (void)clearScreen{
// 清除所有的线,即存在线数组中的对象
[_lineArray removeAllObjects];
// 重绘(具体概念在动画中更明显,这里理解为,接受到了命令,接下来就是点击开始按钮运行)
[self setNeedsDisplay];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// 一触摸屏幕,就将启动点存进pointArray中,并且将绘成第一条线所需的点数组作为元素存进定义的_lineArray中
// 为什么这样设置呢?因为手一离开屏幕,又是一个新的启动点传入,也是另一条新线的划入
NSMutableArray * pointArray = [NSMutableArray arrayWithCapacity:1];
[_lineArray addObject:pointArray];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
// 获得触摸屏幕的所有对象
UITouch * touch = [touches anyObject];
// 获得触摸屏幕的所有点的位置
CGPoint point = [touch locationInView:self];
// 利用NSValue将获得的点封装成NSValue类型对象,以便能存进NSMutableArray中
NSValue * pointCount = [NSValue valueWithCGPoint:point];
// 与touchesBegan方法想呼应,一触摸屏幕所设置的点数组也就是最后一个点数组,这里取出来,存移动中所有点
NSMutableArray * pointArray = [_lineArray lastObject];
[pointArray addObject:pointCount];
// 重新绘制这个self.view
[self setNeedsDisplay];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// 获得上下文本(我更愿意理解为获得进行绘画资格,作为一个通行证般的参数,让你能设置画笔颜色,线条尺寸,以及如何绘画)
CGContextRef context = UIGraphicsGetCurrentContext();
// 设置画笔
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
// 设置线条粗细
CGContextSetLineWidth(context, 2.0);
for (int i = 0; i < _lineArray.count; i++) {
NSMutableArray * pointArray = [_lineArray objectAtIndex:i];
// 这里(int)pointArray.count进行了类型转换,可以思考下是为什么
for (int j = 0; j < (int)pointArray.count - 1; j++) {
// 获得封装的起点
NSValue * headPointValue = [pointArray objectAtIndex:j];
// 获得封装的终点
NSValue * tailPointValue = [pointArray objectAtIndex:(j + 1)];
// 转化为CGPoint类型
CGPoint headPoint = [headPointValue CGPointValue];
// 转化为CGPoint类型
CGPoint tailPoint = [tailPointValue CGPointValue];
// 设置画笔的起点
CGContextMoveToPoint(context, headPoint.x, headPoint.y);
// 画笔路径的途径直到终点
CGContextAddLineToPoint(context, tailPoint.x, tailPoint.y);
}
}
// 绘制这个文本(总算可以画画了)
CGContextStrokePath(context);
}
简单的实现涂鸦功能
最新推荐文章于 2021-01-07 13:26:03 发布