首页 > 代码库 > 源码0308-画板
源码0308-画板
//// DrawView.m// 08-画板#import "DrawView.h"@interface DrawView ()@property (nonatomic, strong) UIBezierPath *path;@property (nonatomic, strong) NSMutableArray *paths;@end@implementation DrawView- (NSMutableArray *)paths{ if (_paths == nil) { _paths = [NSMutableArray array]; } return _paths;}// 仅仅是加载xib的时候调用- (void)awakeFromNib{ [self setUp];}- (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { [self setUp]; } return self;}// 初始化设置- (void)setUp{ // 添加pan手势 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [self addGestureRecognizer:pan];}// 当手指拖动的时候调用- (void)pan:(UIPanGestureRecognizer *)pan{ // 获取当前手指触摸点 CGPoint curP = [pan locationInView:self]; // 获取开始点 if (pan.state == UIGestureRecognizerStateBegan) { // 创建贝瑟尔路径 _path = [UIBezierPath bezierPath]; // 设置路径的起点 [_path moveToPoint:curP]; // 保存描述好的路径 [self.paths addObject:_path]; } // 手指一直在拖动 // 添加线到当前触摸点 [_path addLineToPoint:curP]; // 重绘 [self setNeedsDisplay]; }// 绘制图形// 只要调用drawRect方法就会把之前的内容全部清空- (void)drawRect:(CGRect)rect{ for (UIBezierPath *path in self.paths) { [path stroke]; }}@end
09-画板(小功能)
// ViewController.m// 08-画板#import "ViewController.h"#import "DrawView.h"@interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>@property (weak, nonatomic) IBOutlet DrawView *drawView;@end@implementation ViewController#pragma mark - 清屏- (IBAction)clear:(id)sender { [_drawView clear];}#pragma mark - 撤销- (IBAction)undo:(id)sender { [_drawView undo];}#pragma mark - 橡皮擦- (IBAction)eraser:(id)sender { _drawView.pathColor = [UIColor whiteColor];}#pragma mark - 选择照片- (IBAction)pickerPhoto:(id)sender { // 弹出系统的相册 // 选择控制器(系统相册) UIImagePickerController *picekerVc = [[UIImagePickerController alloc] init]; // 设置选择控制器的来源 // UIImagePickerControllerSourceTypePhotoLibrary 相册集 // UIImagePickerControllerSourceTypeSavedPhotosAlbum:照片库 picekerVc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; // 设置代理 picekerVc.delegate = self; // modal [self presentViewController:picekerVc animated:YES completion:nil]; }#pragma mark - UIImagePickerControllerDelegate// 当用户选择一张图片的时候调用- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ // 获取选中的照片 UIImage *image = info[UIImagePickerControllerOriginalImage]; // 把选中的照片画到画板上 _drawView.image = image; // dismiss [self dismissViewControllerAnimated:YES completion:nil];}#pragma mark - 保存- (IBAction)save:(id)sender { // 截屏 // 开启上下文 UIGraphicsBeginImageContextWithOptions(_drawView.bounds.size, NO, 0); // 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 渲染图层 [_drawView.layer renderInContext:ctx]; // 获取上下文中的图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 关闭上下文 UIGraphicsEndImageContext(); // 保存画板的内容放入相册 // image:写入的图片 // completionTarget图片保存监听者 // 注意:以后写入相册方法中,想要监听图片有没有保存完成,保存完成的方法不能随意乱写 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); }// 监听保存完成,必须实现这个方法- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ NSLog(@"保存图片成功");}- (void)savePhoto{ }- (IBAction)colorChange:(UIButton *)sender { // 给画板传递颜色 _drawView.pathColor = sender.backgroundColor; }- (IBAction)valueChange:(UISlider *)sender { // 给画板传递线宽 _drawView.lineWidth = sender.value; }- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
//// DrawView.h// 08-画板#import <UIKit/UIKit.h>@interface DrawView : UIView@property (nonatomic, strong) UIColor *pathColor;@property (nonatomic, assign) NSInteger lineWidth;@property (nonatomic, strong) UIImage *image;// 清屏- (void)clear;// 撤销- (void)undo;@end
//// DrawView.m// 08-画板#import "DrawView.h"#import "DrawPath.h"@interface DrawView ()@property (nonatomic, strong) DrawPath *path;@property (nonatomic, strong) NSMutableArray *paths;@end@implementation DrawView- (void)setImage:(UIImage *)image{ _image = image; [self.paths addObject:_image]; // 重绘 [self setNeedsDisplay];}- (void)clear{ [self.paths removeAllObjects]; [self setNeedsDisplay];}- (void)undo{ [self.paths removeLastObject]; [self setNeedsDisplay];}- (NSMutableArray *)paths{ if (_paths == nil) { _paths = [NSMutableArray array]; } return _paths;}// 仅仅是加载xib的时候调用- (void)awakeFromNib{ [self setUp];}- (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { [self setUp]; } return self;}// 初始化设置- (void)setUp{ // 添加pan手势 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [self addGestureRecognizer:pan]; _lineWidth = 1; _pathColor = [UIColor blackColor];}// 当手指拖动的时候调用- (void)pan:(UIPanGestureRecognizer *)pan{ // 获取当前手指触摸点 CGPoint curP = [pan locationInView:self]; // 获取开始点 if (pan.state == UIGestureRecognizerStateBegan) { // 创建贝瑟尔路径 _path = [[DrawPath alloc] init]; // 设置线宽 _path.lineWidth = _lineWidth; // 给路径设置颜色 _path.pathColor = _pathColor; // 设置路径的起点 [_path moveToPoint:curP]; // 保存描述好的路径 [self.paths addObject:_path]; } // 手指一直在拖动 // 添加线到当前触摸点 [_path addLineToPoint:curP]; // 重绘 [self setNeedsDisplay]; }// 绘制图形// 只要调用drawRect方法就会把之前的内容全部清空- (void)drawRect:(CGRect)rect{ for (DrawPath *path in self.paths) { if ([path isKindOfClass:[UIImage class]]) { // 绘制图片 UIImage *image = (UIImage *)path; [image drawInRect:rect]; }else{ // 画线 [path.pathColor set]; [path stroke]; } }}@end
//// DrawPath.h// 08-画板#import <UIKit/UIKit.h>@interface DrawPath : UIBezierPath@property (nonatomic, strong) UIColor *pathColor;@end
//// DrawPath.m// 08-画板#import "DrawPath.h"@implementation DrawPath@end
01-画板(图片处理)
//// ViewController.m// 08-画板#import "ViewController.h"#import "ImageHandleView.h"#import "DrawView.h"@interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>@property (weak, nonatomic) IBOutlet DrawView *drawView;@end@implementation ViewController#pragma mark - 清屏- (IBAction)clear:(id)sender { [_drawView clear];}#pragma mark - 撤销- (IBAction)undo:(id)sender { [_drawView undo];}#pragma mark - 橡皮擦- (IBAction)eraser:(id)sender { _drawView.pathColor = [UIColor whiteColor];}#pragma mark - 选择照片- (IBAction)pickerPhoto:(id)sender { // 弹出系统的相册 // 选择控制器(系统相册) UIImagePickerController *picekerVc = [[UIImagePickerController alloc] init]; // 设置选择控制器的来源 // UIImagePickerControllerSourceTypePhotoLibrary 相册集 // UIImagePickerControllerSourceTypeSavedPhotosAlbum:照片库 picekerVc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; // 设置代理 picekerVc.delegate = self; // modal [self presentViewController:picekerVc animated:YES completion:nil]; }#pragma mark - UIImagePickerControllerDelegate// 当用户选择一张图片的时候调用- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ // 获取选中的照片 UIImage *image = info[UIImagePickerControllerOriginalImage]; // 创建一个图片处理的View ImageHandleView *imageHandleV = [[ImageHandleView alloc] initWithFrame:self.drawView.bounds]; imageHandleV.handleCompletionBlock = ^(UIImage *image){ self.drawView.image = image; }; imageHandleV.handleBeginBlock = ^{ self.drawView.userInteractionEnabled = NO; }; [self.drawView addSubview:imageHandleV]; // 做图片的处理 imageHandleV.image = image; // // 把选中的照片画到画板上// _drawView.image = image; // dismiss [self dismissViewControllerAnimated:YES completion:nil];}#pragma mark - 保存- (IBAction)save:(id)sender { // 截屏 // 开启上下文 UIGraphicsBeginImageContextWithOptions(_drawView.bounds.size, NO, 0); // 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 渲染图层 [_drawView.layer renderInContext:ctx]; // 获取上下文中的图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 关闭上下文 UIGraphicsEndImageContext(); // 保存画板的内容放入相册 // image:写入的图片 // completionTarget图片保存监听者 // 注意:以后写入相册方法中,想要监听图片有没有保存完成,保存完成的方法不能随意乱写 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); }// 监听保存完成,必须实现这个方法- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ NSLog(@"保存图片成功");}- (IBAction)colorChange:(UIButton *)sender { // 给画板传递颜色 _drawView.pathColor = sender.backgroundColor; }- (IBAction)valueChange:(UISlider *)sender { // 给画板传递线宽 _drawView.lineWidth = sender.value; }- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
//// DrawView.h// 08-画板#import <UIKit/UIKit.h>@interface DrawView : UIView@property (nonatomic, strong) UIColor *pathColor;@property (nonatomic, assign) NSInteger lineWidth;@property (nonatomic, strong) UIImage *image;// 清屏- (void)clear;// 撤销- (void)undo;@end
//// DrawView.m// 08-画板#import "DrawView.h"#import "DrawPath.h"@interface DrawView ()@property (nonatomic, strong) DrawPath *path;@property (nonatomic, strong) NSMutableArray *paths;@end@implementation DrawView- (void)setImage:(UIImage *)image{ _image = image; [self.paths addObject:_image]; // 重绘 [self setNeedsDisplay];}- (void)clear{ [self.paths removeAllObjects]; [self setNeedsDisplay];}- (void)undo{ [self.paths removeLastObject]; [self setNeedsDisplay];}- (NSMutableArray *)paths{ if (_paths == nil) { _paths = [NSMutableArray array]; } return _paths;}// 仅仅是加载xib的时候调用- (void)awakeFromNib{ [self setUp];}- (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { [self setUp]; } return self;}// 初始化设置- (void)setUp{ // 添加pan手势 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [self addGestureRecognizer:pan]; _lineWidth = 1; _pathColor = [UIColor blackColor];}// 当手指拖动的时候调用- (void)pan:(UIPanGestureRecognizer *)pan{ // 获取当前手指触摸点 CGPoint curP = [pan locationInView:self]; // 获取开始点 if (pan.state == UIGestureRecognizerStateBegan) { // 创建贝瑟尔路径 _path = [[DrawPath alloc] init]; // 设置线宽 _path.lineWidth = _lineWidth; // 给路径设置颜色 _path.pathColor = _pathColor; // 设置路径的起点 [_path moveToPoint:curP]; // 保存描述好的路径 [self.paths addObject:_path]; } // 手指一直在拖动 // 添加线到当前触摸点 [_path addLineToPoint:curP]; // 重绘 [self setNeedsDisplay]; }// 绘制图形// 只要调用drawRect方法就会把之前的内容全部清空- (void)drawRect:(CGRect)rect{ for (DrawPath *path in self.paths) { if ([path isKindOfClass:[UIImage class]]) { // 绘制图片 UIImage *image = (UIImage *)path; [image drawInRect:rect]; }else{ // 画线 [path.pathColor set]; [path stroke]; } }}@end
//// DrawPath.h// 08-画板#import <UIKit/UIKit.h>@interface DrawPath : UIBezierPath@property (nonatomic, strong) UIColor *pathColor;@end
//// DrawPath.m// 08-画板#import "DrawPath.h"@implementation DrawPath@end
//// ImageHandleView.h// 08-画板#import <UIKit/UIKit.h>@interface ImageHandleView : UIView@property (nonatomic, strong) UIImage *image;@property (nonatomic, strong) void(^handleCompletionBlock)(UIImage *image);@property (nonatomic, strong) void(^handleBeginBlock)();@end
//// ImageHandleView.m// 08-画板#import "ImageHandleView.h"@interface ImageHandleView ()<UIGestureRecognizerDelegate>@property (nonatomic, weak) UIImageView *imageV;@end@implementation ImageHandleView- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ // 如果点在UIImageView, return self.imageV;}- (UIImageView *)imageV{ if (_imageV == nil) { UIImageView *imageV = [[UIImageView alloc] initWithFrame:self.bounds]; imageV.userInteractionEnabled = YES; _imageV = imageV; // 添加手势 [self setUpGestureRecognizer]; [self addSubview:imageV]; } return _imageV;}#pragma mark - 添加手势- (void)setUpGestureRecognizer{ // 平移 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [_imageV addGestureRecognizer:pan]; // 旋转 UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)]; rotation.delegate = self; [_imageV addGestureRecognizer:rotation]; // 缩放 UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; pinch.delegate = self; [_imageV addGestureRecognizer:pinch]; // 长按 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; [_imageV addGestureRecognizer:longPress];}- (void)pan:(UIPanGestureRecognizer *)pan{ // 获取手指的偏移量 CGPoint transP = [pan translationInView:self.imageV]; // 设置UIImageView的形变 self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, transP.x, transP.y); // 复位:只要想要相对于上一次就必须复位 [pan setTranslation:CGPointZero inView:self.imageV];}- (void)rotation:(UIRotationGestureRecognizer *)rotation{ self.imageV.transform = CGAffineTransformRotate(self.imageV.transform, rotation.rotation); rotation.rotation = 0;}- (void)pinch:(UIPinchGestureRecognizer *)pinch{ self.imageV.transform = CGAffineTransformScale(self.imageV.transform, pinch.scale, pinch.scale); pinch.scale = 1;}- (void)longPress:(UILongPressGestureRecognizer *)longPress{ if (longPress.state == UIGestureRecognizerStateBegan) { // 图片处理完毕 // 高亮的效果 [UIView animateWithDuration:0.25 animations:^{ self.imageV.alpha = 0; } completion:^(BOOL finished) { [UIView animateWithDuration:0.25 animations:^{ self.imageV.alpha = 1; } completion:^(BOOL finished) { // 高亮完成的时候 // 把处理的图片生成一张新的图片,截屏 // 开启位图上下文 UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0); // 获取位图上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 把控件的图层渲染到上下文 [self.layer renderInContext:ctx]; // 获取图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 关闭上下文 UIGraphicsEndImageContext(); // 调用Block if (_handleCompletionBlock) { _handleCompletionBlock(image); } // 移除父控件 [self removeFromSuperview]; }]; }]; }}- (void)setImage:(UIImage *)image{ _image = image; // 展示UIImageView self.imageV.image = image;}#pragma mark - 手势代理方法// 是否同时支持多个手势- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES;}@end
02-画板(图片处理bug)
//// ImageHandleView.m// 08-画板#import "ImageHandleView.h"@interface ImageHandleView ()<UIGestureRecognizerDelegate>@property (nonatomic, weak) UIImageView *imageV;@end@implementation ImageHandleView//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{// NSLog(@"%s",__func__);//}//- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event//{// // 如果点在UIImageView,// return self.imageV;//}- (UIImageView *)imageV{ if (_imageV == nil) { UIImageView *imageV = [[UIImageView alloc] initWithFrame:self.bounds]; imageV.userInteractionEnabled = YES; _imageV = imageV; // 添加手势 [self setUpGestureRecognizer]; [self addSubview:imageV]; } return _imageV;}#pragma mark - 拦截拖动手势- (void)panHandle{ NSLog(@"%s",__func__);}#pragma mark - 添加手势- (void)setUpGestureRecognizer{ // 添加拖动手势给ImageHandleView UIPanGestureRecognizer *panHandle = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandle)]; [self addGestureRecognizer:panHandle]; // 平移 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [_imageV addGestureRecognizer:pan]; // 旋转 UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)]; rotation.delegate = self; [_imageV addGestureRecognizer:rotation]; // 缩放 UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; pinch.delegate = self; [_imageV addGestureRecognizer:pinch]; // 长按 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; [_imageV addGestureRecognizer:longPress];}- (void)pan:(UIPanGestureRecognizer *)pan{ // 获取手指的偏移量 CGPoint transP = [pan translationInView:self.imageV]; // 设置UIImageView的形变 self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, transP.x, transP.y); // 复位:只要想要相对于上一次就必须复位 [pan setTranslation:CGPointZero inView:self.imageV];}- (void)rotation:(UIRotationGestureRecognizer *)rotation{ self.imageV.transform = CGAffineTransformRotate(self.imageV.transform, rotation.rotation); rotation.rotation = 0;}- (void)pinch:(UIPinchGestureRecognizer *)pinch{ self.imageV.transform = CGAffineTransformScale(self.imageV.transform, pinch.scale, pinch.scale); pinch.scale = 1;}- (void)longPress:(UILongPressGestureRecognizer *)longPress{ if (longPress.state == UIGestureRecognizerStateBegan) { // 图片处理完毕 // 高亮的效果 [UIView animateWithDuration:0.25 animations:^{ self.imageV.alpha = 0; } completion:^(BOOL finished) { [UIView animateWithDuration:0.25 animations:^{ self.imageV.alpha = 1; } completion:^(BOOL finished) { // 高亮完成的时候 // 把处理的图片生成一张新的图片,截屏 // 开启位图上下文 UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0); // 获取位图上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 把控件的图层渲染到上下文 [self.layer renderInContext:ctx]; // 获取图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 关闭上下文 UIGraphicsEndImageContext(); // 调用Block if (_handleCompletionBlock) { _handleCompletionBlock(image); } // 移除父控件 [self removeFromSuperview]; }]; }]; }}- (void)setImage:(UIImage *)image{ _image = image; // 展示UIImageView self.imageV.image = image;}#pragma mark - 手势代理方法// 是否同时支持多个手势- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES;}@end
源码0308-画板
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。