画板IOS

实现画板功能.

当手指移动的时候,在中间的画板区域当中进行绘制.由于每一个路径都有不同的状态.所以我们就不能用一条路径来做.
所以要弄一个数组记录住每一条路径.
实现画板功能.
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;
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • --绘图与滤镜全面解析 概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益...
    韩七夏阅读 7,903评论 2 10
  • 精确工具、选取和图层,你值得拥有。 大千世界充满着各式需要克服的设计问题,比如说房屋设计改进、简化我们生活所用小工...
    概念画板阅读 10,879评论 0 10
  • Quartz2D以及drawRect的重绘机制字数1487 阅读21 评论1 喜欢1一、什么是Quartz2D Q...
    PurpleWind阅读 4,308评论 0 3
  • Quartz2D 简介 Quartz2D是二维(平面)的绘图引擎(经包装的函数库,方便开发者使用。也就是说苹果帮我...
    iOS_Cqlee阅读 3,805评论 0 2
  • 小时候喜欢下雨天 是一整天的课余时间 我猜父亲一定不会喜欢下雨天 不然每一次他都是皱着眉头抽着烟 长高后的我爱上了...
    无良少年二十三阅读 1,261评论 0 0

友情链接更多精彩内容