美文网首页
Quartz 2D 小练习 画板

Quartz 2D 小练习 画板

作者: KinKen | 来源:发表于2018-06-08 18:26 被阅读0次

    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 () <UINavigationControllerDelegate,UIImagePickerControllerDelegate,TempUIViewDelegate>
    @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<NSString *,id> *)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 <UIKit/UIKit.h>
    @class TempUIView;
    @protocol TempUIViewDelegate <NSObject>
    -(void)tempUIView:(TempUIView *)tempUIView withImage:(UIImage *)image;
    
    @end
    
    @interface TempUIView : UIView
    @property(nonatomic,strong)UIImage *image;
    
    @property(nonatomic,weak)id<TempUIViewDelegate> 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 小练习 画板

          本文链接:https://www.haomeiwen.com/subject/nannsftx.html