这一节,我将介绍使用Quartz 2D实现的一个实例 -- 涂鸦。在介绍直接,先介绍一下贝塞尔曲线的基本概念。
大致代码:
自定义的模型 DrawModel.h:
@interface DrawModel : NSObject @property (nonatomic, assign) CGFloat lineNewWidth; @property (nonatomic, strong) UIColor *lineNewColor; @property (nonatomic, strong) UIBezierPath *path; @end
@interface DrawView : UIView @property (nonatomic, assign) CGFloat lineNewWidth; @property (nonatomic, strong) UIColor *lineNewColor; - (void)back; - (void)clear; @end
@property (nonatomic,strong) NSMutableArray *infos; - (NSMutableArray *)infos { if (!_infos) { _infos = [NSMutableArray array]; } return _infos; }
- (void)setLineNewWidth:(CGFloat)lineNewWidth { _lineNewWidth = lineNewWidth; } - (void)setLineNewColor:(UIColor *)lineColor { if (lineColor == nil) { _lineNewColor = [UIColor blackColor]; } else { _lineNewColor = lineColor; } }
- (void)back { [self.infos removeLastObject]; [self setNeedsDisplay]; } - (void)clear { [self.infos removeAllObjects]; [self setNeedsDisplay]; }
UIImage *newImage = [UIImage imageWithView:self.paintView]; UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [touches anyObject]; CGPoint startPoint = [touch locationInView:touch.view]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:startPoint]; DrawModel *model = [[DrawModel alloc] init]; model.lineNewWidth = self.lineNewWidth == 0 ? 1: self.lineNewWidth; model.lineNewColor = self.lineNewColor; model.path = path; [self.infos addObject:model]; [self setNeedsDisplay]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint movePoint = [touch locationInView:touch.view]; DrawModel *model = [self.infos lastObject]; UIBezierPath *path = model.path; [path addLineToPoint:movePoint]; [self setNeedsDisplay]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self touchesMoved:touches withEvent:event]; }
1.每次手指按下时,会触发touchesBegan方法,每次创建一个UIBezierPath路径及创建数据模型DrawModel,并且将模型数据放到数组infos中。
2.手指拖动的时候,会触发touchesMoved方法,立刻从数组infos中取出拖拽前创建的UIBezierPath,并且将绘制所有的点的集合保存在贝塞尔曲线中。
3.手指抬起的时候,会触发touchesEnded方法,理论上只有一个点,但也应该完成最终的绘制,由于他所做得工作和touchesMoved一致,所以直接调用touchesMoved方法即可。
关键绘制代码如下:
- (void)drawRect:(CGRect)rect { for (DrawModel *model in self.infos) { UIBezierPath *path = model.path; path.lineWidth = model.lineNewWidth; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; [model.lineNewColor set]; [path stroke]; } }