一、在Main.storyboard中拖入一个UIView,用于显示绘制的线条,将Class属性改成自定义类(此类继承UIView,处理触控事件并绘制线条),并拖三个UIButton用于处理返回上级、清空画板、保存相册的点击事件,代码如下:
#import "ViewController.h"
@interface ViewController ()
//UIView引用
@property (weak, nonatomic) IBOutlet CMHuaBan *huabanV;
//三个点击事件监听方法
- (IBAction)onBackClick:(id)sender;
- (IBAction)onClearClick:(id)sender;
- (IBAction)onSaveClick:(id)sender;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
/*
*/
- (IBAction)onBackClick:(id)sender {
//调用自定义类中的自定义返回方法
[self.huabanV back];
}
- (IBAction)onClearClick:(id)sender {
//调用自定义类中的自定义清空方法
[self.huabanV clear];
}
- (IBAction)onSaveClick:(id)sender {
//调用自定义类中的自定义保存方法
[self.huabanV save];
}
@end
二、新建自定义CMHuaBan,继承UIView,处理画板的各种拖动事件以及绘制线条:
思路:
(1)创建path的集合成员变量,用于存储每条path的值;
(2)监听touchesBegan方法(down事件),创建path,创建线的起点xy值,并设置path的一些属性;
(3)监听touchesMoved(move事件)和touchesEnded(up事件)方法,创建path的其他点;
(4)重写drawRect方法,循环绘制每一条path。
1.CMHuaBan.h代码,主要定义三个方法供外部调用,处理清空、返回、保存操作:
#import <UIKit/UIKit.h>
@interface CMHuaBan : UIView
- (void) clear;
- (void) back;
- (void) save;
@end
2.CMHuaBan.m代码如下:
#import "CMHuaBan.h"
@interface CMHuaBan()
@property (nonatomic, strong) NSMutableArray *pathList;
@end
@implementation CMHuaBan
/*
懒加载初始化list集合
*/
- (NSMutableArray *)list{
if(_pathList == nil){
_pathList = [NSMutableArray array];
}
return _pathList;
}
/*
UIView方法,绘制path路径
*/
- (void)drawRect:(CGRect)rect {
//设置path的颜色
[[UIColor redColor] set];
//循环绘制绘制path路径
for (UIBezierPath *path in self.pathList) {
[path stroke];
}
}
/*
自定义方法,将点存入列表
*/
- (void)addPoint:(NSSet<UITouch *> *)touches isReset:(BOOL *)isReset{
//获取UITouch
UITouch *touch = [touches anyObject];
//获取当前点的值CGPoint
CGPoint point = [touch locationInView:touch.view];
UIBezierPath *path = nil;
if(isReset){//如果是按下,则新建一个列表存放新的path集合
path = [UIBezierPath bezierPath];
//设置线宽
path.lineWidth = 10;
//设置线头圆角
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
//创建path的起点
[path moveToPoint:point];
[self.pathList addObject:path];
} else {//移动与松开时,获取最后一个列表
path = [self.pathList lastObject];
//创建path的其他点
[path addLineToPoint:point];
}
//刷新,触发drawRect绘制
[self setNeedsDisplay];
}
/*
UIView方法,按下手指时触发
*/
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if(self.pathList == nil){
self.pathList = [NSMutableArray array];
}
//调用自定义方法,将path存入列表
[self addPoint:touches isReset:YES];
}
/*
UIView方法,拖动手指时触发
*/
- (void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//调用自定义方法,将path存入列表
[self addPoint:touches isReset:NO];
}
/*
UIView方法,松开手指时触发
*/
- (void) touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//调用自定义方法,将path存入列表
[self addPoint:touches isReset:NO];
}
/*
清空画板
*/
- (void) clear{
if([self.pathList count] == 0){
return;
}
//清空path列表
[self.pathList removeAllObjects];
//重绘
[self setNeedsDisplay];
}
/*
返回上一次绘制
*/
- (void) back{
if([self.pathList count] == 0){
return;
}
//删除最后一个path列表
[self.pathList removeLastObject];
//重绘
[self setNeedsDisplay];
}
/*
截图保存
*/
- (void) save{
if([self.pathList count] == 0){
return;
}
/*
将当前View截图
*/
//开启上下文
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
//将当前View的layer渲染到上下文
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
//取出图片
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
//结束上下文
UIGraphicsEndImageContext();
//保存图片到相册
UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
/*
保存相册回调方法
*/
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
if(error){
NSLog(@"保存失败");
} else {
NSLog(@"保存成功");
}
}
@end
三、打开Info.plist文件,在"<dict>"节点的末尾添加写相册的权限:
<dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>请求获取读取媒体资料库的权限</string>
<dict>