iOS简单画板开发案例分享

2020-01-15 13:58:57于丽

- (void)pan:(UIPanGestureRecognizer *)pan {
   
  //获取开始的触摸点
  CGPoint startP = [pan locationInView:self];
   
  if (pan.state == UIGestureRecognizerStateBegan) {
     
    //创建贝塞尔路径
    _path = [[DrawPath alloc]init];
    _path.lineWidth = _lineWidth;
    _path.pathColor = _pathColor;
     
    //不能在手指抬起时将路径添加到数组,因为在遍历数组画线时路径还没有被添加到数组里面
    [_pathArr addObject:_path];
     
    //设置起点
    [_path moveToPoint:startP];
     
  }
   
  //连线
  [_path addLineToPoint:startP];
   
  //重绘,调用drawRect方法
  [self setNeedsDisplay];
   
}

画线实现drawRect方法,绘制线条或者图片时,是把数组中的路径全部画出来


- (void)drawRect:(CGRect)rect {
   
  //把所有路径画出来
  for (DrawPath *path in self.pathArr) {
     
    if ([path isKindOfClass:[UIImage class]]) {
      //画图
      UIImage *image = (UIImage *)path;
      [image drawInRect:rect];
    }else {
      //画线
      [path.pathColor set];
      [path stroke];
    }
  }
   
}

当把图片添加到画板时


- (void)setImage:(UIImage *)image {
   
  _image = image;
   
  [self.pathArr addObject:image];
   
  //重绘调用drawRect才能在画板上显示图片
  [self setNeedsDisplay];
}

还可以把直接更新路径数组的操作封装在画板中

 


- (void)clear {
  //清除
  [self.pathArr removeAllObjects];
   
  [self setNeedsDisplay];
   
}
 
- (void)undo {
  //撤销
  [self.pathArr removeLastObject];
   
  [self setNeedsDisplay];
}

控制器中:


@interface ViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (weak, nonatomic) IBOutlet DrawView *drawView;
@end

实现几个按钮对画板的操作:


- (IBAction)clear:(id)sender {
   
  //清屏
  [_drawView clear];
   
}
 
- (IBAction)undo:(id)sender {
   
  //撤销
  [_drawView undo];
   
}
 
- (IBAction)eraser:(id)sender {
   
  //擦除 就是把路径的颜色设置为画板的背景色,假象
  _drawView.pathColor = _drawView.backgroundColor;
  _drawView.lineWidth = 20;
   
}
 
- (IBAction)changeLineWidth:(UISlider *)sender {
   
  //改变路径线宽
  _drawView.lineWidth = sender.value;
   
}
 
- (IBAction)changeColor:(UIButton *)sender {
   
   
  //改变路径颜色
  _drawView.pathColor = sender.backgroundColor;
   
}
 
- (IBAction)pickPhoto:(id)sender {
   
  //选择照片
  //弹出系统相册
  UIImagePickerController *picker = [[UIImagePickerController alloc]init];
   
  //设置选择控制器的来源 UIImagePickerControllerSourceTypeSavedPhotosAlbum:照片库
  picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
   
  //设置代理
  picker.delegate = self;
   
  //modal出控制器
  [self presentViewController:picker animated:YES completion:nil];
   
}
 
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
   
  //获取选择的图片
  UIImage *image = info[UIImagePickerControllerOriginalImage];
   
  //创建一个处理图片的view
  ImageHandleView *handleView = [[ImageHandleView alloc]initWithFrame:self.drawView.bounds];
   
  handleView.handleCompletionBlock = ^(UIImage *image){
     
    _drawView.image = image;
  };
   
  [self.drawView addSubview:handleView];
   
  //将图片画在画板上
  handleView.image = image;
   
  //_drawView.image = image;
   
  //dismiss
  [self dismissViewControllerAnimated:YES completion:nil];
  //NSLog(@"%@", info);
   
}
 
- (IBAction)save:(id)sender {
   
  [UIView animateWithDuration:0.15 animations:^{
    //保存当前画板上的内容
     
    //开启上下文
    UIGraphicsBeginImageContextWithOptions(_drawView.bounds.size, NO, 0);
     
    //获取位图上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
     
    //把控件上的图层渲染到上下文
    [_drawView.layer renderInContext:ctx];
     
    //获取上下文中的图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
     
    //关闭上下文
    UIGraphicsEndImageContext();
     
    //保存图片到相册
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
     
    self.drawView.alpha = 0;
  } completion:^(BOOL finished) {
    [UIView animateWithDuration:0.15 animations:^{
      self.drawView.alpha = 1;
    }];
  }];
   
}
 
//保存成功后的方法必须是这个,不能随便写
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
   
  NSLog(@"保存成功");
   
}