project navigator
project navigatorpngstoaryBoard
storyBoardcode
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.
网友评论