Quartz 2D 小练习 画板

project navigator

project navigatorpng

stoaryBoard

storyBoard

code

ViewController.m

//
//  ViewController.m
//  0607画板
//
//  Created by Kinken_Yuen on 2018/6/7.
//  Copyright © 2018年 Kinken_Yuen. All rights reserved.
//

#import "ViewController.h"
#import "ContextView.h"
#import "TempUIView.h"

@interface ViewController () 
@property (weak, nonatomic) IBOutlet ContextView *ContextView;

@property(nonatomic,strong)TempUIView *tempUIView;

@end

@implementation ViewController
//清屏
- (IBAction)clear:(id)sender {
    [self.ContextView clear];
}

//撤销
- (IBAction)undo:(id)sender {
    [self.ContextView undo];
}

//擦除
- (IBAction)eraser:(id)sender {
    [self.ContextView eraser];
}

//打开照片
- (IBAction)photo:(id)sender {
    UIImagePickerController *pickC = [[UIImagePickerController alloc] init];
    pickC.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    pickC.delegate = self;
    [self presentViewController:pickC animated:YES completion:nil];
}

//选择图片后调用
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    UIImage *newImage = info[UIImagePickerControllerOriginalImage];
    
    //用一个透明UIView作图片的容器
    TempUIView *tempview = [[TempUIView alloc] initWithFrame:self.ContextView.frame];
    tempview.delegate =self;
    tempview.backgroundColor = [UIColor clearColor];
    tempview.image = newImage;
    self.tempUIView = tempview;
    [self.view addSubview:tempview];
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - TempUIViewDelegate
-(void)tempUIView:(TempUIView *)tempUIView withImage:(UIImage *)image{
    self.ContextView.image = image;
}



//保存
- (IBAction)save:(id)sender {
    //开启上下文
    UIGraphicsBeginImageContextWithOptions(self.ContextView.bounds.size, NO, 0);
    //渲染到上下文
    [self.ContextView.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    //取得照片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    //关闭上下文
    UIGraphicsEndImageContext();
    
    //保存到系统相册
    //必须实现方法image:didFinishSavingWithError:contextInfo:
    UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

//保存涂鸦成功后执行
- (void)image:(UIImage *)image
didFinishSavingWithError:(NSError *)error
  contextInfo:(void *)contextInfo{
    
}

//设置线宽
- (IBAction)sliderChanged:(UISlider *)sender {
    [self.ContextView setLineWith:sender];
}

//设置颜色
- (IBAction)setColor:(UIButton *)sender {
    [self.ContextView setLineColor:sender.backgroundColor];
}

- (IBAction)closePhoto:(id)sender {
    [self.tempUIView removeFromSuperview];
}

- (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

ContextView.m

//
//  ContextView.m
//  0607画板
//
//  Created by Kinken_Yuen on 2018/6/7.
//  Copyright © 2018年 Kinken_Yuen. All rights reserved.
//

#import "ContextView.h"
#import "MyBezierPath.h"

@interface ContextView ()
/*存储当前绘制路径*/
@property(nonatomic,strong)UIBezierPath *path;

/*存储所有绘制路径*/
@property(nonatomic,strong)NSMutableArray *pathArray;

/*设置线宽*/
@property(nonatomic,assign)CGFloat lWith;

/*设置的线条颜色*/
@property(nonatomic,strong)UIColor *lColor;

@end

@implementation ContextView
-(NSMutableArray *)pathArray{
    if (_pathArray == nil) {
        _pathArray = [NSMutableArray array];
    }
    return _pathArray;
}

-(void)awakeFromNib{
    [super awakeFromNib];
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [self addGestureRecognizer:pan];
    self.lWith = 1;
    self.lColor = [UIColor blackColor];
}

-(void)pan:(UIPanGestureRecognizer *)pan{
    CGPoint curP = [pan locationInView:self];
    if (pan.state == UIGestureRecognizerStateBegan){
        MyBezierPath *path = [[MyBezierPath alloc] init];
        [path setLineWidth:self.lWith];
        path.lColor = self.lColor;
        self.path = path;
        [self.pathArray addObject:path];
        [path moveToPoint:curP];
    }else if (pan.state == UIGestureRecognizerStateChanged){
        [self.path addLineToPoint:curP];
         [self setNeedsDisplay];
    }
    
}

-(void)drawRect:(CGRect)rect{
    //绘制所有路径
    for (MyBezierPath *path in self.pathArray) {
        if ([path isKindOfClass:[UIImage class]]) {
            UIImage *image = (UIImage *)path;
            [image drawInRect:self.bounds];
        }else{
            [path.lColor set];
            [path stroke];
        }
    }
}

//清屏
-(void)clear{
    [self.pathArray removeAllObjects];
    [self setNeedsDisplay];
}

//撤销
-(void)undo{
    [self.pathArray removeLastObject];
    [self setNeedsDisplay];
}

//擦除,白色线条覆盖
-(void)eraser{
   self.lColor = [UIColor whiteColor];
}

//设置线宽
-(void)setLineWith:(UISlider *)slider{
    self.lWith = slider.value;
}

//设置线条颜色
-(void)setLineColor:(UIColor *)color{
    self.lColor = color;
}

- (void)setImage:(UIImage *)image{
    _image = image;
    [self.pathArray addObject:image];
    //重绘
    [self setNeedsDisplay];
}

@end


@end

TempUIView.h

//
//  TempUIView.h
//  0607画板
//
//  Created by Kinken_Yuen on 2018/6/8.
//  Copyright © 2018年 Kinken_Yuen. All rights reserved.
//

#import 
@class TempUIView;
@protocol TempUIViewDelegate 
-(void)tempUIView:(TempUIView *)tempUIView withImage:(UIImage *)image;

@end

@interface TempUIView : UIView
@property(nonatomic,strong)UIImage *image;

@property(nonatomic,weak)id delegate;

@end

TempUIView.m

//
//  TempUIView.m
//  0607画板
//
//  Created by Kinken_Yuen on 2018/6/8.
//  Copyright © 2018年 Kinken_Yuen. All rights reserved.
//

#import "TempUIView.h"
@interface TempUIView ()
@property(nonatomic,strong)UIImageView *imageV;

@end


@implementation TempUIView
- (UIImageView *)imageV{
    if (_imageV == nil) {
        UIImageView *imageV = [[UIImageView alloc] init];
        imageV.frame = self.bounds;
        [self addGesture:imageV];
        [self addSubview:imageV];
        _imageV = imageV;
    }
    return  _imageV;
}

-(void)setImage:(UIImage *)image{
    _image = image;
    self.imageV.image = image;
}

-(void)addGesture:(UIImageView *)imageView{
    imageView.userInteractionEnabled = YES;
    //添加手势
    //拖拽
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [imageView addGestureRecognizer:pan];
    
    //缩放
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
    [imageView addGestureRecognizer:pinch];
    
    //旋转
    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
    [imageView addGestureRecognizer:rotation];
    
    //长按
    UILongPressGestureRecognizer *longP = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longP:)];
    [imageView addGestureRecognizer:longP];
}

-(void)pan:(UIPanGestureRecognizer *)pan{
    CGPoint point = [pan translationInView:pan.view];
    pan.view.transform =CGAffineTransformTranslate(pan.view.transform, point.x, point.y);
    [pan setTranslation:CGPointZero inView:pan.view];
}

-(void)pinch:(UIPinchGestureRecognizer *)pinch{
    pinch.view.transform = CGAffineTransformScale(pinch.view.transform, pinch.scale, pinch.scale);
    [pinch setScale:1];
}

-(void)rotation:(UIRotationGestureRecognizer *)rotation{
    rotation.view.transform = CGAffineTransformRotate(rotation.view.transform, rotation.rotation);
    [rotation setRotation:0];
}

-(void)longP:(UILongPressGestureRecognizer *)longP{
    if (longP.state == UIGestureRecognizerStateBegan) {
        [UIView animateWithDuration:0.2 animations:^{
            self.imageV.alpha = 0;
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.2 animations:^{
                self.imageV.alpha = 1;
            }completion:^(BOOL finished) {
                UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
                [self.layer renderInContext:UIGraphicsGetCurrentContext()];
                UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
                //代理:将图片传给画板
                if ([self.delegate respondsToSelector:@selector(tempUIView:withImage:)]) {
                    [self.delegate tempUIView:self withImage:newImage];
                }
                [self removeFromSuperview];
            }];
        }];
    }
}

@end


访问系统相册需要加入权限:
info.plist添加Privacy - Photo Library Additions Usage Description,Type 选择 String,Value 中输入你的提示语。
否则运行提示:

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.

你可能感兴趣的:(Quartz 2D 小练习 画板)