iOS

1、绘制画板

1.1 绘制简单画板

  • PaintBoardView.h

    	@interface PaintBoardView : UIView
    	
    	@end
    
  • PaintBoardView.m

    	@interface PaintBoardView ()
    	
    	/// 路径
    	@property (nonatomic, strong) UIBezierPath *path;
    	
    	/// 保存所有路径的数组
    	@property (nonatomic, strong) NSMutableArray *pathsArrayM;
    	
    	@end
    	
    	@implementation PaintBoardView
    	
    	/// 初始化
    	- (instancetype)initWithFrame:(CGRect)frame {
    	    
    	    if (self = [super initWithFrame:frame]) {
    	        self.backgroundColor = [UIColor whiteColor];
    	    }
    	    return self;
    	}
    
    	/// 触摸开始
    	- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    	    
    	    // 获取触摸起始点位置
    	    CGPoint startPoint = [touches.anyObject locationInView:self];
    	    
    	    // 添加路径描绘起始点
    	    [self.path moveToPoint:startPoint];
    	    
    	    // 添加一条触摸路径描绘
    	    [self.pathsArrayM addObject:self.path];
    	}
    	
    	/// 触摸移动
    	- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    	    
    	    // 获取触摸点位置
    	    CGPoint touchPoint = [touches.anyObject locationInView:self];
    	    
    	    // 添加路径描绘
    	    [self.path addLineToPoint:touchPoint];
    	    
    	    // 刷新视图
    	    [self setNeedsDisplay];
    	}
    	
    	/// 触摸结束
    	- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
    		// 获取绘制结果
    		UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
    		CGContextRef ctx = UIGraphicsGetCurrentContext();
    		[self.layer renderInContext:ctx];
    		UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    		UIGraphicsEndImageContext();
    		    
    		NSData *data = UIImagePNGRepresentation(image);
    		[data writeToFile:@"/Users/JHQ0228/Desktop/Images/pic.png" atomically:YES];
    	}
    	
    	/// 触摸取消
    	- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event {
    	    [self touchesEnded:touches withEvent:event];
    	}
    	
    	/// 绘制图形
    	- (void)drawRect:(CGRect)rect {
    	    
    	    for (UIBezierPath *path in self.pathsArrayM) {
    	        
    	        // 绘制路径
    	        [path stroke];
    	    }
    	}
    	
    	/// 懒加载
    	
    	- (UIBezierPath *)path {
    	    
    	    if (_path == nil) {
    	        _path = [UIBezierPath bezierPath];
    	    }
    	    return _path;
    	}
    	
    	- (NSMutableArray *)pathsArrayM {
    	    
    	    if (_pathsArrayM == nil) {
    	        _pathsArrayM = [NSMutableArray array];
    	    }
    	    return _pathsArrayM;
    	}
    	
    	@end
    
  • ViewController.m

        // 创建画板
        CGRect frame = CGRectMake(20, 50, self.view.bounds.size.width - 40, 200);
        PaintBoardView *paintBoard = [[PaintBoardView alloc] initWithFrame:frame];
        
        [self.view addSubview:paintBoard];
    
  • 效果

    Quartz2D102 Quartz2D103

1.2 绘制画板封装

  • 具体实现代码见 GitHub 源码 QExtension

  • QPaintBoardPath.h

    	@interface QPaintBoardPath : UIBezierPath
    	
    	/// 线的颜色
    	@property (nonatomic, strong) UIColor *pathColor;
    	
    	/// 线的宽度
    	@property (nonatomic, assign) CGFloat pathWidth;
    	
    	@end
    
  • QPaintBoardPath.m

    	@implementation QPaintBoardPath
    	
    	@end
    
  • QPaintBoardView.h

    	@interface QPaintBoardView : UIView
    	
    	/// 画线的宽度,default is 1,max is 30
    	@property (nonatomic, assign) CGFloat paintLineWidth;
    	
    	/// 画笔的颜色,default is blackColor
    	@property (nonatomic, strong) UIColor *paintLineColor;
    	
    	/// 画板的颜色,default is whiteColor
    	@property (nonatomic, strong) UIColor *paintBoardColor;
    	
    	/**
    	 *  创建画板视图控件,获取绘画结果
    	 *
    	 *  @param frame        画板视图控件 frame
    	 *  @param lineWidth    画笔的线宽,default is 1,max is 30
    	 *  @param lineColor    画笔的颜色,default is blackColor
    	 *  @param boardColor   画板的颜色,default is whiteColor
    	 *  @param result       绘画结果
    	 *
    	 *  @return 手势锁视图控件
    	 */
    	+ (instancetype)q_paintBoardViewWithFrame:(CGRect)frame
    	                                lineWidth:(CGFloat)lineWidth
    	                                lineColor:(nullable UIColor *)lineColor
    	                               boardColor:(nullable UIColor *)boardColor
    	                              paintResult:(void (^)(UIImage * _Nullable image))result;
    	
    	/**
    	 *  创建简单画板视图控件
    	 *
    	 *  @param frame    画板视图控件 frame
    	 *
    	 *  @return 手势锁视图控件
    	 */
    	+ (instancetype)q_paintBoardViewWithFrame:(CGRect)frame;
    	
    	/**
    	 *  获取绘画结果
    	 *
    	 *  @return 绘画结果图片
    	 */
    	- (UIImage * _Nullable)q_getPaintImage;
    	
    	/**
    	 *  清除绘画结果
    	 */
    	- (void)q_clear;
    	
    	/**
    	 *  撤销绘画结果
    	 */
    	- (void)q_back;
    	
    	@end
    
  • QPaintBoardView.m

    	#import "QPaintBoardPath.h"
    
    	@interface QPaintBoardView ()
    	
    	/// 路径
    	@property (nonatomic, strong, nullable) QPaintBoardPath *path;
    	
    	/// 保存所有路径的数组
    	@property (nonatomic, strong) NSMutableArray *pathsArrayM;
    	
    	/// 绘画结果
    	@property (nonatomic, copy) void (^resultBlock)(UIImage * _Nullable);
    	
    	/// 按钮工具条
    	@property (nonatomic, strong) UIView *toolView;
    	
    	/// 画笔设置视图
    	@property (nonatomic, strong) UIView *brushSetingView;
    	
    	/// 颜色选择视图
    	@property (nonatomic, strong) UIScrollView *colorSelectedView;
    	
    	/// 画板设置视图
    	@property (nonatomic, strong) UIScrollView *boardSetingView;
    	
    	/// 记录线的颜色
    	@property (nonatomic, strong) UIColor *lastPaintLineColor;
    	
    	/// 记录线的宽度
    	@property (nonatomic, assign) CGFloat lastPaintLineWidth;
    	
    	@end
    	
    	@implementation QPaintBoardView
    	
    	#pragma mark - 创建画板
    	
    	/// 创建画板视图控件,获取绘画结果
    	+ (instancetype)q_paintBoardViewWithFrame:(CGRect)frame
    	                                lineWidth:(CGFloat)lineWidth
    	                                lineColor:(nullable UIColor *)lineColor
    	                               boardColor:(nullable UIColor *)boardColor
    	                              paintResult:(void (^)(UIImage * _Nullable image))result {
    	    
    	    QPaintBoardView *paintBoardView = [[self alloc] init];
    	    
    	//    CGRect tmpFrame = frame;
    	//    tmpFrame.size.height = frame.size.height + 44;
    	    
    	    paintBoardView.frame = frame;
    	    paintBoardView.paintLineWidth = (lineWidth > 30 ? 30 : lineWidth) ? : 1;
    	    paintBoardView.paintLineColor = lineColor ? : [UIColor blackColor];
    	    paintBoardView.paintBoardColor = boardColor ? : [UIColor whiteColor];
    	    paintBoardView.resultBlock = result;
    	    
    	    return paintBoardView;
    	}
    	
    	/// 创建简单画板视图控件
    	+ (instancetype)q_paintBoardViewWithFrame:(CGRect)frame {
    	    
    	    QPaintBoardView *paintBoardView = [[self alloc] initWithFrame:frame];
    	    
    	    paintBoardView.paintLineWidth = 1;
    	    paintBoardView.paintLineColor = [UIColor blackColor];
    	    paintBoardView.paintBoardColor = [UIColor whiteColor];
    	    
    	    return paintBoardView;
    	}
    	
    	#pragma mark - 自定义画板
    	
    	/// 初始化,自定义画板界面
    	- (instancetype)init {
    	    
    	    if (self = [super init]) {
    	        
    	        self.clipsToBounds = YES;
    	        
    	        // 添加工具按钮视图
    	        
    	        self.toolView = [[UIView alloc] init];
    	        self.toolView.backgroundColor = [UIColor blackColor];
    	        [self addSubview:self.toolView];
    	        
    	        NSArray *imageNames = @[@"btn_brush", @"btn_board", @"btn_eraser", @"btn_back", @"btn_clear", @"btn_save"];
    	        NSArray *selectedImageNames = @[@"btn_brush_pressed", @"btn_board_pressed", @"btn_eraser_pressed"];
    	        
    	        for (NSUInteger i = 0; i < 6; i++) {
    	            
    	            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    	            button.tag = i;
    	            [button setBackgroundImage:[self q_getBundleImageWithName:imageNames[i]] forState:UIControlStateNormal];
    	            [button addTarget:self action:@selector(toolButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    	            [self.toolView addSubview:button];
    	            
    	            if (i < 3) {
    	                [button setBackgroundImage:[self q_getBundleImageWithName:selectedImageNames[i]] forState:UIControlStateSelected];
    	            }
    	        }
    	        
    	        // 添加画笔设置视图
    	        
    	        self.brushSetingView = [[UIView alloc] init];
    	        self.brushSetingView.backgroundColor = [UIColor grayColor];
    	        [self addSubview:self.brushSetingView];
    	        [self sendSubviewToBack:self.brushSetingView];
    	        
    	        UIView *widthBackView = [[UIView alloc] init];
    	        widthBackView.layer.borderWidth = 1;
    	        widthBackView.layer.borderColor = [UIColor lightGrayColor].CGColor;
    	        UIView *widthView = [[UIView alloc] init];
    	        [widthBackView addSubview:widthView];
    	        [self.brushSetingView addSubview:widthBackView];
    	        
    	        UISlider *widthSlider = [[UISlider alloc] init];
    	        widthSlider.thumbTintColor = [UIColor orangeColor];
    	        [widthSlider addTarget:self action:@selector(widthSliderClick:) forControlEvents:UIControlEventValueChanged];
    	        [self.brushSetingView addSubview:widthSlider];
    	        
    	        UIButton *colorSelectedBtn = [[UIButton alloc] init];
    	        colorSelectedBtn.layer.borderWidth = 1;
    	        colorSelectedBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
    	        [colorSelectedBtn addTarget:self action:@selector(colorSelectedBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    	        [self.brushSetingView addSubview:colorSelectedBtn];
    	        
    	        // 添加画笔颜色选择视图
    	        
    	        self.colorSelectedView = [[UIScrollView alloc] init];
    	        self.colorSelectedView.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.3];
    	        self.colorSelectedView.showsHorizontalScrollIndicator = NO;
    	        [self addSubview:self.colorSelectedView];
    	        [self sendSubviewToBack:self.colorSelectedView];
    	        
    	        NSArray *colorArray = @[[UIColor blackColor], [UIColor whiteColor], [UIColor redColor],
    	                                [UIColor greenColor], [UIColor blueColor], [UIColor cyanColor],
    	                                [UIColor magentaColor], [UIColor orangeColor], [UIColor yellowColor],
    	                                [UIColor darkGrayColor], [UIColor lightGrayColor], [UIColor brownColor],
    	                                [UIColor grayColor], [UIColor purpleColor]];
    	        
    	        for (NSUInteger i = 0; i < 14; i++) {
    	            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    	            button.layer.borderWidth = 1;
    	            button.layer.borderColor = [UIColor lightGrayColor].CGColor;
    	            [button setBackgroundColor:colorArray[i]];
    	            [button addTarget:self action:@selector(colorSelectedClick:) forControlEvents:UIControlEventTouchUpInside];
    	            [self.colorSelectedView addSubview:button];
    	        }
    	        
    	        // 添加画板设置视图
    	        
    	        self.boardSetingView = [[UIScrollView alloc] init];
    	        self.boardSetingView.backgroundColor = [UIColor grayColor];
    	        self.boardSetingView.showsHorizontalScrollIndicator = NO;
    	        [self addSubview:self.boardSetingView];
    	        [self sendSubviewToBack:self.boardSetingView];
    	        
    	        for (NSUInteger i = 0; i < 14; i++) {
    	            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    	            button.layer.borderWidth = 1;
    	            button.layer.borderColor = [UIColor lightGrayColor].CGColor;
    	            [button setBackgroundColor:colorArray[i]];
    	            [button addTarget:self action:@selector(boardColorSelectedClick:) forControlEvents:UIControlEventTouchUpInside];
    	            [self.boardSetingView addSubview:button];
    	        }
    	    }
    	    return self;
    	}
    	
    	/// 布局子控件
    	- (void)layoutSubviews {
    	    [super layoutSubviews];
    	    
    	    if (self.subviews.count) {
    	        
    	        // 设置工具按钮视图
    	        
    	        self.toolView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 44);
    	        
    	        for (NSUInteger i = 0; i < 6; i++) {
    	            CGFloat margin = (self.bounds.size.width - 44 * 6) / 7;
    	            CGFloat x = margin + (margin + 44) * i;
    	            self.toolView.subviews[i].frame = CGRectMake(x, 0, 44, 44);
    	        }
    	        
    	        // 设置画笔设置视图
    	        
    	        self.brushSetingView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    	        
    	        self.brushSetingView.subviews[0].frame = CGRectMake(15, 15, 30, 30);
    	        self.brushSetingView.subviews[0].layer.cornerRadius = 15;
    	        self.brushSetingView.subviews[0].layer.masksToBounds = YES;
    	        
    	        CGFloat w = self.paintLineWidth;
    	        self.brushSetingView.subviews[0].subviews[0].frame = CGRectMake(15 - w / 2, 15 - w / 2, w, w);
    	        self.brushSetingView.subviews[0].subviews[0].layer.cornerRadius = w / 2;
    	        self.brushSetingView.subviews[0].subviews[0].layer.masksToBounds = YES;
    	        self.brushSetingView.subviews[0].subviews[0].backgroundColor = self.paintLineColor;
    	        
    	        self.brushSetingView.subviews[1].frame = CGRectMake(60, 15, self.bounds.size.width - 60 - 80, 32);
    	        UISlider *slider = self.brushSetingView.subviews[1];
    	        slider.value = self.paintLineWidth / 30;
    	        
    	        self.brushSetingView.subviews[2].frame = CGRectMake(self.bounds.size.width - 60, 15, 50, 30);
    	        self.brushSetingView.subviews[2].backgroundColor = self.paintLineColor;
    	        
    	        // 设置画笔颜色选择视图
    	        
    	        self.colorSelectedView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    	        self.colorSelectedView.contentSize = CGSizeMake(14 * (50 + 20) + 20, 50);
    	        
    	        for (NSUInteger i = 0; i < 14; i++) {
    	            CGFloat x = 20 + (20 + 50) * i;
    	            self.colorSelectedView.subviews[i].frame = CGRectMake(x, 10, 50, 40);
    	        }
    	        
    	        // 设置画板设置视图
    	        
    	        self.boardSetingView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    	        self.boardSetingView.contentSize = CGSizeMake(14 * (50 + 20) + 20, 50);
    	        
    	        for (NSUInteger i = 0; i < 14; i++) {
    	            CGFloat x = 20 + (20 + 50) * i;
    	            self.boardSetingView.subviews[i].frame = CGRectMake(x, 10, 50, 40);
    	        }
    	    }
    	}
    	
    	/// 工具按钮点击事件处理
    	- (void)toolButtonClick:(UIButton *)btn {
    	    
    	    switch (btn.tag) {
    	            
    	        case 0: {
    	            // 画笔设置
    	            
    	            [self exitEraseState];
    	            
    	            if (btn.isSelected == NO) {
    	                
    	                [self hideBoardSetingView];
    	                
    	                [self showColorSelectedView];
    	                [self showBrushSetingView];
    	                
    	            } else {
    	                
    	                [self hideColorSelectedView];
    	                [self hideBrushSetingView];
    	            }
    	            break;
    	        }
    	            
    	        case 1: {
    	            // 画板设置
    	            
    	            [self exitEraseState];
    	            
    	            if (btn.isSelected == NO) {
    	                
    	                [self hideColorSelectedView];
    	                [self hideBrushSetingView];
    	                
    	                [self showBoardSetingView];
    	                
    	            } else {
    	                
    	                [self hideBoardSetingView];
    	            }
    	            break;
    	        }
    	            
    	        case 2: {
    	            // 擦除
    	            
    	            [self hideBoardSetingView];
    	            
    	            [self hideColorSelectedView];
    	            [self hideBrushSetingView];
    	            
    	            if (btn.selected == NO) {
    	                
    	                [self enterEraseState];
    	                
    	            } else {
    	                [self exitEraseState];
    	            }
    	            break;
    	        }
    	            
    	        case 3: {
    	            // 撤销
    	            
    	            [self hideBoardSetingView];
    	            
    	            [self hideColorSelectedView];
    	            [self hideBrushSetingView];
    	            
    	            [self q_back];
    	        
    	            break;
    	        }
    	            
    	        case 4: {
    	            // 清除
    	            
    	            [self hideBoardSetingView];
    	            
    	            [self hideColorSelectedView];
    	            [self hideBrushSetingView];
    	            
    	            [self exitEraseState];
    	            
    	            [self q_clear];
    	            
    	            break;
    	        }
    	            
    	        case 5: {
    	            // 获取绘制结果
    	            
    	            [self hideBoardSetingView];
    	            
    	            [self hideColorSelectedView];
    	            [self hideBrushSetingView];
    	            
    	            [self exitEraseState];
    	            
    	            if (self.resultBlock) {
    	                self.resultBlock([self q_getPaintImage]);
    	            }
    	            
    	            break;
    	        }
    	            
    	        default:
    	            break;
    	    }
    	}
    	
    	/// 画笔线宽设置按钮点击事件处理
    	- (void)widthSliderClick:(UISlider *)slider {
    	    
    	    if (slider.value == 0) {
    	        self.paintLineWidth = 1;
    	    } else {
    	        self.paintLineWidth = slider.value * 30;
    	    }
    	    
    	    CGFloat w = self.paintLineWidth;
    	    self.brushSetingView.subviews[0].subviews[0].frame = CGRectMake(15 - w / 2, 15 - w / 2, w, w);
    	    self.brushSetingView.subviews[0].subviews[0].layer.cornerRadius = w / 2;
    	}
    	
    	/// 画笔颜色选择按钮点击事件处理
    	- (void)colorSelectedBtnClick:(UIButton *)btn {
    	    
    	    if (btn.selected == NO) {
    	        [self showColorSelectedView];
    	    } else {
    	        [self hideColorSelectedView];
    	    }
    	}
    	
    	/// 画笔颜色选择点击响应事件处理
    	- (void)colorSelectedClick:(UIButton *)btn {
    	    
    	    self.paintLineColor = btn.backgroundColor;
    	    
    	    self.brushSetingView.subviews[0].subviews[0].backgroundColor = btn.backgroundColor;
    	    self.brushSetingView.subviews[2].backgroundColor = btn.backgroundColor;
    	}
    	
    	/// 画板颜色选择点击响应事件处理
    	- (void)boardColorSelectedClick:(UIButton *)btn {
    	    
    	    self.paintBoardColor = btn.backgroundColor;
    	}
    	
    	/// 显示画笔设置视图
    	- (void)showBrushSetingView {
    	    
    	    UIButton *setBrushBtn = self.toolView.subviews[0];
    	    
    	    if (setBrushBtn.selected == NO) {
    	        
    	        setBrushBtn.selected = YES;
    	        
    	        [UIView animateWithDuration:0.2 animations:^{
    	            CGRect frame = CGRectMake(0, self.bounds.size.height - 44 - 60, self.bounds.size.width, 60);
    	            self.brushSetingView.frame = frame;
    	        }];
    	    }
    	}
    	
    	/// 隐藏画笔设置视图
    	- (void)hideBrushSetingView {
    	    
    	    UIButton *setBrushBtn = self.toolView.subviews[0];
    	    
    	    if (setBrushBtn.selected) {
    	        
    	        setBrushBtn.selected = NO;
    	        
    	        [UIView animateWithDuration:0.2 animations:^{
    	            CGRect frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    	            self.brushSetingView.frame = frame;
    	        }];
    	    }
    	}
    	
    	// 显示画笔颜色选择视图
    	- (void)showColorSelectedView {
    	    
    	    UIButton *colorSelectedBtn = self.brushSetingView.subviews[2];
    	    
    	    if (colorSelectedBtn.selected == NO) {
    	        
    	        colorSelectedBtn.selected = YES;
    	        
    	        [UIView animateWithDuration:0.2 animations:^{
    	            CGRect frame = CGRectMake(0, self.bounds.size.height - 44 - 60 - 60, self.bounds.size.width, 60);
    	            self.colorSelectedView.frame = frame;
    	        }];
    	    }
    	}
    	
    	/// 隐藏画笔颜色选择视图
    	- (void)hideColorSelectedView {
    	    
    	    UIButton *colorSelectedBtn = self.brushSetingView.subviews[2];
    	    
    	    if (colorSelectedBtn.selected) {
    	        
    	        colorSelectedBtn.selected = NO;
    	        
    	        [UIView animateWithDuration:0.2 animations:^{
    	            CGRect frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    	            self.colorSelectedView.frame = frame;
    	        }];
    	    }
    	}
    	
    	/// 显示画板设置视图
    	- (void)showBoardSetingView {
    	    
    	    UIButton *setBoardBtn = self.toolView.subviews[1];
    	    
    	    if (setBoardBtn.selected == NO) {
    	        
    	        setBoardBtn.selected = YES;
    	        
    	        [UIView animateWithDuration:0.2 animations:^{
    	            CGRect frame = CGRectMake(0, self.bounds.size.height - 44 - 60, self.bounds.size.width, 60);
    	            self.boardSetingView.frame = frame;
    	        }];
    	    }
    	}
    	
    	/// 隐藏画板设置视图
    	- (void)hideBoardSetingView {
    	    
    	    UIButton *setBoardBtn = self.toolView.subviews[1];
    	    
    	    if (setBoardBtn.selected) {
    	        
    	        setBoardBtn.selected = NO;
    	        
    	        [UIView animateWithDuration:0.2 animations:^{
    	            CGRect frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    	            self.boardSetingView.frame = frame;
    	        }];
    	    }
    	}
    	
    	/// 进入擦除状态
    	- (void)enterEraseState {
    	    
    	    UIButton *setEraseBtn = self.toolView.subviews[2];
    	    
    	    if (setEraseBtn.selected == NO) {
    	        
    	        setEraseBtn.selected = YES;
    	        
    	        self.lastPaintLineColor = self.paintLineColor;
    	        self.paintLineColor = self.paintBoardColor;
    	        
    	        self.lastPaintLineWidth = self.paintLineWidth;
    	        self.paintLineWidth = self.paintLineWidth + 5;
    	    }
    	}
    	
    	/// 退出擦除状态
    	- (void)exitEraseState {
    	    
    	    UIButton *setEraseBtn = self.toolView.subviews[2];
    	    
    	    if (setEraseBtn.isSelected) {
    	        
    	        setEraseBtn.selected = NO;
    	        
    	        self.paintLineColor = self.lastPaintLineColor;
    	        self.paintLineWidth = self.lastPaintLineWidth;
    	    }
    	}
    	
    	#pragma mark - 绘制图案
    	
    	/// 触摸开始
    	- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    	    
    	    if (self.subviews.count) {
    	        
    	        [self hideColorSelectedView];
    	        [self hideBrushSetingView];
    	        [self hideBoardSetingView];
    	    }
    	    
    	    // 获取触摸起始点位置
    	    CGPoint startPoint = [touches.anyObject locationInView:self];
    	    
    	    // 添加路径描绘起始点
    	    [self.path moveToPoint:startPoint];
    	    
    	    // 记录线的属性
    	    self.path.pathColor = self.paintLineColor;
    	    self.path.pathWidth = self.paintLineWidth;
    	    
    	    // 添加一条触摸路径描绘
    	    [self.pathsArrayM addObject:self.path];
    	}
    	
    	/// 触摸移动
    	- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    	    
    	    // 获取触摸点位置
    	    CGPoint touchPoint = [touches.anyObject locationInView:self];
    	    
    	    // 添加路径描绘
    	    [self.path addLineToPoint:touchPoint];
    	    
    	    // 刷新视图
    	    [self setNeedsDisplay];
    	}
    	
    	/// 触摸结束
    	- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    	    
    	    // 销毁 path
    	    self.path = nil;
    	}
    	
    	/// 触摸取消
    	- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event {
    	    [self touchesEnded:touches withEvent:event];
    	}
    	
    	/// 绘制图形,只要调用 drawRect 方法就会把之前的内容全部清空
    	- (void)drawRect:(CGRect)rect {
    	    
    	    for (QPaintBoardPath *path in self.pathsArrayM) {
    	        
    	        // 绘制路径
    	        path.lineWidth = path.pathWidth;
    	        [path.pathColor setStroke];
    	        
    	        path.lineCapStyle = kCGLineCapRound;
    	        path.lineJoinStyle = kCGLineJoinRound;
    	        [path stroke];
    	    }
    	}
    	
    	/// 获取绘画结果
    	- (UIImage * _Nullable)q_getPaintImage {
    	    
    	    UIImage *image = nil;
    	    
    	    CGSize boardSize = self.bounds.size;
    	    
    	    if (self.subviews.count) {
    	        boardSize.height = self.bounds.size.height - 44;
    	    }
    	    
    	    if (self.pathsArrayM.count) {
    	        UIGraphicsBeginImageContextWithOptions(boardSize, NO, 0);
    	        CGContextRef ctx = UIGraphicsGetCurrentContext();
    	        [self.layer renderInContext:ctx];
    	        image = UIGraphicsGetImageFromCurrentImageContext();
    	        UIGraphicsEndImageContext();
    	    }
    	    
    	    return image;
    	}
    	
    	/// 清除绘画结果
    	- (void)q_clear {
    	    
    	    if (self.pathsArrayM.count) {
    	        [self.pathsArrayM removeAllObjects];
    	        
    	        [self setNeedsDisplay];
    	    }
    	}
    	
    	/// 撤销绘画结果
    	- (void)q_back {
    	    
    	    if (self.pathsArrayM.count) {
    	        [self.pathsArrayM removeLastObject];
    	        
    	        [self setNeedsDisplay];
    	    }
    	}
    	
    	/// 懒加载
    	
    	- (QPaintBoardPath * _Nullable)path {
    	    
    	    // path 每次绘制完成后需要销毁,否则无法清除之前绘制的路径
    	    
    	    if (_path == nil) {
    	        _path = [QPaintBoardPath bezierPath];
    	    }
    	    return _path;
    	}
    	
    	- (NSMutableArray *)pathsArrayM {
    	    
    	    if (_pathsArrayM == nil) {
    	        _pathsArrayM = [NSMutableArray array];
    	    }
    	    return _pathsArrayM;
    	}
    	
    	/// 设置属性值
    	- (void)setPaintBoardColor:(UIColor *)paintBoardColor {
    	    _paintBoardColor = paintBoardColor;
    	    self.backgroundColor = paintBoardColor;
    	}
    	
    	/// 加载 bundle 中的图片
    	- (UIImage *)q_getBundleImageWithName:(NSString *)name {
    	    
    	    NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"QPaintBoardView.bundle"];
    	    
    	    UIImage *image = [[UIImage imageWithContentsOfFile:[bundlePath stringByAppendingPathComponent:name]]
    	                      imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    	    return image;
    	}
    	
    	@end
    
  • 1、创建简单画板

    	// 创建简单画板
    	CGRect frame = CGRectMake(20, 50, self.view.bounds.size.width - 40, 200);
    	    
    	QPaintBoardView *paintBoardView = [QPaintBoardView q_paintBoardViewWithFrame:frame];
    	    
    	// 可选属性值设置
    	paintBoardView.paintLineWidth = 5;                         // default is 1
    	paintBoardView.paintLineColor = [UIColor redColor];        // default is blackColor
    	paintBoardView.paintBoardColor = [UIColor cyanColor];      // default is whiteColor
    	
    	[self.view addSubview:paintBoardView];
    	self.paintBoardView = paintBoardView;
    	
    	// 撤销绘画结果
    	[self.paintBoardView q_back];
    	    
    	// 清除绘画结果
    	[self.paintBoardView q_clear];
    	    
    	// 获取绘画结果
    	UIImage *image = [self.paintBoardView q_getPaintImage];
    
    • 效果

      Quartz2D104 Quartz2D105

  • 2、创建画板

    	// 创建画板
    	QPaintBoardView *paintBoard = [QPaintBoardView q_paintBoardViewWithFrame:self.view.bounds
    	                                                               lineWidth:0
    	                                                               lineColor:nil
    	                                                              boardColor:nil
    	                                                             paintResult:^(UIImage * _Nullable image) {
    	                                                                 
    	    if (image) {
    	        NSData *data = UIImagePNGRepresentation(image);
    	        [data writeToFile:@"/Users/JHQ0228/Desktop/Images/pic.png" atomically:YES];
    	    }
    	}];
    	    
    	[self.view addSubview:paintBoard];
    
    • 效果

      Quartz2D106 Quartz2D107

      Quartz2D108 Quartz2D109

      Quartz2D110 Quartz2D111

原文地址:https://www.cnblogs.com/QianChia/p/6286346.html