实现画板功能.
当手指移动的时候,在中间的画板区域当中进行绘制.由于每一个路径都有不同的状态.所以我们就不能用一条路径来做.
所以要弄一个数组记录住每一条路径.
实现画板功能.
1.监听手指在屏幕上的状态.在开始点击屏幕的时候,创建一个路径.并把手指当前的点设为路径的起点.
弄一个成员属性记录当前绘制的路径.并把当前的路径添加到路径数组当中.
2.当手指在移动的时候,用当前的路径添加一根线到当前手指所在的点.然后进行重绘.
3.在绘图方法当中.取出所有的路径.把所有的路径给绘制出来.
3.1设置路径属性.
提供属性方法.
清屏功能:删除所有路径进行重绘
撤销功能:删除最后一条路径,进行重绘
设置线宽:由于每一条线宽度都不样.所以要在开始创建路径的时,就要添加一个成员属性,设置一个默认值.
在把当前路径添加到路径数组之前,设置好线的宽度.然后重写线宽属性方法.
下一次再创建路径时,线的宽度就是当前设置的宽度.
设置线的颜色:同样,由于每一条线的颜色也不一样.也需要记录住每一条路径的颜色.
由于UIBezierPath没有给我们直接提供设置颜色的属性.我们可以自定义一个UIBezierPath.
创建一个MyBezierPath类,继承UIBezierPath,在该类中添加一个颜色的属性.
在创建路径的时候,直接使用自己定义的路径.设置路径默认的一个颜色.方法给设置线宽一样.
在绘图过程中, 取出来的都是MyBezierPath,把MyBezierPath的颜色设置路径的颜色.
橡皮擦功能:橡皮擦功能其实就是把路径的颜色设为白色.
- 4.保存绘制的图片到相册.
保存相册的思路:就是把绘制的在View上的内容生成一张图片,保存到系统相册当中.
具体步骤:
开启一个跟View相同大小的图片上下文.
把View的layer上面内容渲染到上下文当中.
生成一张图片,把图片保存到上下文.
关闭上下文.
如何把一张图片保存到上下文?
调用方法:
参数说明:
第一个参数:要写入到相册的图片.
第二个参数:哪个对象坚听写入完成时的状态.
第三个参数:图片保存完成时调用的方法
UIImageWriteToSavedPhotosAlbum(newImage,
self,
@selector(image:didFinishSavingWithError: contextInfo:),nil);
注意:图片保存完成时调用的方法必须得是image:didFinishSavingWithError: contextInfo:
-
5.选择图片.
点击图片时弹出系统的相册.
如果弹出系统的相册?
使用UIImagePickerController控件器Modal出它来.
UIImagePickerController *pick = [[UIImagePickerController alloc] init];设置照片的来源 pick.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; 设置代码,监听选择图片,UIImagePickerController比较特殊,它需要遵守两个协议 <UINavigationControllerDelegate,UIImagePickerControllerDelegate> pick.delegate = self; modal出控件器 [self presentViewController:pick animated:YES completion:nil]; 注意没有实现代码方法时,选择一张照片会自动的dismiss掉相册控制器.但是设置代码后,就得要自己去dismiss了 实现代理方法. 选择的照片就在这个方法第二个参数当中, 它是一个字典 -(void)imagePickerController:(nonnull UIImagePickerController *)picker didFinishPickingMediaWithInfo:(nonnull NSDictionary<NSString *,id> *)info{ 获取当前选中的图片.通过UIImagePickerControllerOriginalImage就能获取. UIImage *image = info[UIImagePickerControllerOriginalImage]; } 获取完图片后.图片是能够缩放,平移的,因此获取完图片后,是在画板板View上面添加了一个UIView. 只有UIView才能做平移,缩放,旋转等操作. 因此做法为.在图片选择完毕后,添加一个和画板View相同大小的UIView,这个UIView内部有一个UIImageView. 对这个UIImageView进行一些手势操作.操作完成时.长按图片,把View的内容截屏,生成一张图片. 把新生成的图片绘制到画板上面. 6.绘制图片.
在画板View当中提供一个UImage属性,供外界传递.重写属性的set方法,每次传递图片时进行重绘
画图片也有有序的,所以要把图片也添加到路径数组当中.
在绘图片过过程当中,如果发现取出来的是一个图片类型.那就直接图片绘制到上下文当中.代码 绘图部分
- (NSMutableArray *)allPathArray {
if (_allPathArray == nil) {
_allPathArray = [NSMutableArray array];
}
return _allPathArray;
}
- (void)awakeFromNib {
//添加手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self addGestureRecognizer:pan];
self.width = 1;
self.color = [UIColor blackColor];
}
-(void)setImage:(UIImage *)image {
_image = image;
//添加图片添加到数组当中
[self.allPathArray addObject:image];
//重绘
[self setNeedsDisplay];
}
//清屏
- (void)clear {
//清空所有的路径
[self.allPathArray removeAllObjects];
//重绘
[self setNeedsDisplay];
}
//撤销
- (void)undo {
//删除最后一个路径
[self.allPathArray removeLastObject];
//重绘
[self setNeedsDisplay];
}
//橡皮擦
- (void)erase {
[self setLineColor:[UIColor whiteColor]];
}
//设置线的宽度
- (void)setLineWith:(CGFloat)lineWidth {
self.width = lineWidth;
}
//设置线的颜色
- (void)setLineColor:(UIColor *)color {
self.color = color;
}
- (void)pan:(UIPanGestureRecognizer *)pan {
//获取的当前手指的点
CGPoint curP = [pan locationInView:self];
//判断手势的状态
if(pan.state == UIGestureRecognizerStateBegan) {
//创建路径
//UIBezierPath *path = [UIBezierPath bezierPath];
MyBezierPath *path = [[MyBezierPath alloc] init];
self.path = path;
//设置起点
[path moveToPoint:curP];
//设置线的宽度
[path setLineWidth:self.width];
//设置线的颜色
//什么情况下自定义类:当发现系统原始的功能,没有办法瞒足自己需求时,这个时候,要自定义类.继承系统原来的东西.再去添加属性自己的东西.
path.color = self.color;
[self.allPathArray addObject:path];
} else if(pan.state == UIGestureRecognizerStateChanged) {
//绘制一根线到当前手指所在的点
[self.path addLineToPoint:curP];
//重绘
[self setNeedsDisplay];
}
}
-(void)drawRect:(CGRect)rect {
//绘制保存的所有路径
for (MyBezierPath *path in self.allPathArray) {
//判断取出的路径真实类型
if([path isKindOfClass:[UIImage class]]) {
UIImage *image = (UIImage *)path;
[image drawInRect:rect];
}else {
[path.color set];
[path stroke];
}
}
}
- 添加图片部分
-(UIImageView *)imageV {
if (_imageV == nil) {
UIImageView *imageV = [[UIImageView alloc] init];
imageV.frame = self.bounds;
imageV.userInteractionEnabled = YES;
[self addSubview:imageV];
_imageV = imageV;
//添加手势
[self addGes];
}
return _imageV;
}
-(void)setImage:(UIImage *)image {
_image = image;
NSLog(@"%@",self.imageV);
self.imageV.image = image;
}
//添加手势
-(void)addGes{
// pan
// 拖拽手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(pan:)];
[self.imageV addGestureRecognizer:pan];
// pinch
// 捏合
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
pinch.delegate = self;
[self.imageV addGestureRecognizer:pinch];
//添加旋转
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
rotation.delegate = self;
[self.imageV addGestureRecognizer:rotation];
// 长按手势
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.imageV addGestureRecognizer:longPress];
}
//捏合的时候调用.
- (void)pinch:(UIPinchGestureRecognizer *)pinch
{
pinch.view.transform = CGAffineTransformScale( pinch.view.transform, pinch.scale, pinch.scale);
// 复位
pinch.scale = 1;
}
//旋转的时候调用
- (void)rotation:(UIRotationGestureRecognizer *)rotation
{
// 旋转图片
rotation.view.transform = CGAffineTransformRotate(rotation.view.transform, rotation.rotation);
// 复位,只要想相对于上一次旋转就复位
rotation.rotation = 0;
}
//长按的时候调用
// 什么时候调用:长按的时候调用,而且只要手指不离开,拖动的时候会一直调用,手指抬起的时候也会调用
- (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;
//把当前的View做一个截屏
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文.
UIGraphicsEndImageContext();
//调用代理方法
if([self.delegate respondsToSelector:@selector(handleImageView:newImage:)]) {
[self.delegate handleImageView:self newImage:newImage];
}
//从父控件当中移除
[self removeFromSuperview];
}];
}];
}
}
//拖动的时候调用
- (void)pan:(UIPanGestureRecognizer *)pan{
CGPoint transP = [pan translationInView:pan.view];
pan.view.transform = CGAffineTransformTranslate(pan.view.transform, transP.x, transP.y);
//复位
[pan setTranslation:CGPointZero inView:pan.view];
}
//能够同时支持多个手势
-(BOOL)gestureRecognizer:(nonnull UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(nonnull UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}