先说下具体的功能,包括画笔的绘画,颜色的变化,透明度的设置。以及清屏和橡皮擦对一个路径的擦除功能。
首先,定义了一个绘画的类LCSStroke,里边声明了一些画笔的属性,例如绘画的路径,颜色,画笔的宽度等。直接上代码
LCSStroke.h代码
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#pragma store CGContextRef info
//可变的路径
typedef struct CGPath *CGMutablePathRef;
//默认的模式。前景图会覆盖背景图
typedef enum CGBlendMode CGBlendMode;
@interface LCSStroke : NSObject
@property (nonatomic) CGMutablePathRef path;
@property (nonatomic, assign) CGBlendMode blendMode;
//宽度
@property (nonatomic, assign) CGFloat strokeWidth;
//线的颜色
@property (nonatomic, strong) UIColor *lineColor;
//开始点
@property (nonatomic, assign) CGPoint orignalPoint;
//结束点
@property (nonatomic, assign) CGPoint endPoint;
//颜色的透明度
@property (nonatomic, assign) CGFloat strokeAlpha;
//绘制
- (void)strokeWithContext:(CGContextRef)context;
@end
LCSStroke.m中只有一个方法,就是实现了.h中声明的方法
#import "LCSStroke.h"
@implementation LCSStroke
- (void)strokeWithContext:(CGContextRef)context{
CGContextSetStrokeColorWithColor(context, [_lineColor CGColor]);
CGContextSetLineWidth(context, _strokeWidth);
CGContextSetBlendMode(context, _blendMode);
CGContextSetAlpha(context, _strokeAlpha);
CGContextBeginPath(context);
CGContextAddPath(context, _path);
CGContextStrokePath(context);
}
@end
然后,就是自定义的绘制图形的LCSDrawCustomView了,主要是通过touchesBegan、touchesMoved两个方法获取绘制的点,然后传递给LCSStroke实现绘制。
LCSDrawCustomView.h代码
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface LCSDrawCustomView : UIView
/*清屏*/
- (void)clearScreen;
/*撤销*/
- (void)revokeScreen;
/*设置画笔的颜色*/
- (void)setStrokeColor:(UIColor *)lineColor;
/*设置画笔的大小*/
- (void)setStrokeWidth:(CGFloat)lineWidth;
/*设置橡皮擦*/
- (void)setStrokeEaser:(BOOL)isEaser;
@end
LCSDrawCustomView.m代码
#import "LCSDrawCustomView.h"
#import "LCSStroke.h"
@interface LCSDrawCustomView(){
CGMutablePathRef currentPath;//当前路径
}
@property (nonatomic, assign) BOOL isEaser;
//存储所有的路径
@property (nonatomic, strong) NSMutableArray *stroks;
//画笔颜色
@property (nonatomic, strong) UIColor *lineColor;
//画笔粗细
@property (nonatomic, assign) CGFloat lineWidth;
@property (nonatomic, strong) LCSStroke *stroke;
@end
@implementation LCSDrawCustomView
//init func background must be clearcolor
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){
_stroks = [[NSMutableArray alloc] initWithCapacity:1];
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
currentPath = CGPathCreateMutable();
LCSStroke *stroke = [[LCSStroke alloc] init];
stroke.path = currentPath;
stroke.blendMode = kCGBlendModeNormal;
stroke.strokeWidth = _lineWidth;
stroke.lineColor = _lineColor;
stroke.strokeAlpha = 0.5;
stroke.orignalPoint = point;
_stroke = stroke;
[_stroks addObject:stroke];
CGPathMoveToPoint(currentPath, NULL, point.x, point.y);
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
if(!_isEaser){//简单的绘画
CGPathAddLineToPoint(currentPath, &CGAffineTransformIdentity, point.x, point.y);
}else{//橡皮
for (LCSStroke *stoke in _stroks) {
if(CGPathContainsPoint(stoke.path, NULL, point, FALSE)){//碰撞检测
[_stroks removeObject:stoke];
break;
}
}
}
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect{
CGContextRef context = UIGraphicsGetCurrentContext();
for (LCSStroke *stoke in _stroks) {
[stoke strokeWithContext:context];
}
}
//clear the array
- (void)clearScreen{
_isEaser = NO;
[_stroks removeAllObjects];
[self setNeedsDisplay];
}
-(void)revokeScreen{
_isEaser = NO;
[_stroks removeLastObject];
[self setNeedsDisplay];
}
- (void)setStrokeColor:(UIColor *)lineColor{
_isEaser = NO;
self.lineColor = lineColor;
}
- (void)setStrokeWidth:(CGFloat)lineWidth{
_isEaser = NO;
self.lineWidth = lineWidth;
}
- (void)setStrokeEaser:(BOOL)isEaser{
_isEaser = isEaser;
}
- (void)dealloc{
CGPathRelease(currentPath);
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
然后就是调用了
_drawView = [[LCSDrawCustomView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
_drawView.backgroundColor = [UIColor yellowColor];
[_drawView setStrokeColor:[UIColor redColor]];
[_drawView setStrokeWidth:3];
[self.view addSubview:_drawView];
整个过程还是比较好理解的,可以直接查看下边demo的代码