效果图

设计要求

1、画笔能设置大小、颜色

2、有清屏、撤销、橡皮擦、导入照片功能

3、能将绘好的画面保存到相册

实现思路

1、画笔的实现,我们可以通过监听用户的 平移手势 中创建 UIBezierPath 来实现线条的绘制

2、撤销功能,我们先来看下撤销功能,我们会想到用一个数组队列将用户的每一次的笔画都加入到数组中,然后撤销的时候只需要将最后添加进去的笔画pop掉,重新绘制就可以了

3、清屏功能就简单了,只需要将上面说到的那个数组清空重新绘制下就可以了

4、导入照片功能,可以用系统的 UIImagePickerController 选取照片得到UIImage,然后再将 UIImage 绘制到屏幕中就可以了

5、保存到相册功能,可以使用 UIGraphicsGetImageFromCurrentImageContext 获取当前的图片上下文,得到屏幕画面的 UIImage ,然后通过 UIImageWriteToSavedPhotosAlbum 写入到相册

具体代码实现

1、先画个界面

2、因为我们绘制线条会用到 UIBezierPath ,并且要能可设置颜色,但是UIBezierPath是没有设置颜色的属性,所以我们这里需要简单扩展一下,创建一个继承于 UIBezierPath 的子类 DrawPath

//
// DrawPath.h
// 画板
//
// Created by xgao on 16/4/13.
// Copyright © 2016年 xgao. All rights reserved.
// #import <UIKit/UIKit.h> @interface DrawPath : UIBezierPath

// 画笔颜色
@property(nonatomic,retain)UIColor* pathColor; @end

这个子类只需要扩展一个属性,就是 pathColor 用来保存画笔的颜色

//
// DrawPath.m
// 画板
//
// Created by xgao on 16/4/13.
// Copyright © 2016年 xgao. All rights reserved.
// #import "DrawPath.h" @implementation DrawPath @end

DrawPath.m 里面不需要做其它功能

3、接到来我们对画板功能的实现封装一下,创建一个继承于UIView的 DrawView子类

//
// DrawView.h
// 画板
//
// Created by xgao on 16/4/13.
// Copyright © 2016年 xgao. All rights reserved.
// #import <UIKit/UIKit.h> @interface DrawView : UIView // 画线的宽度
@property(nonatomic,assign)CGFloat lineWidth; // 线条颜色
@property(nonatomic,retain)UIColor* pathColor; // 加载背景图片
@property(nonatomic,strong)UIImage* image; // 清屏
- (void)clear; // 撤销
- (void)undo; // 橡皮擦
- (void)eraser; // 保存
- (void)save; @end
//
// DrawView.m
// 画板
//
// Created by xgao on 16/4/13.
// Copyright © 2016年 xgao. All rights reserved.
// #import "DrawView.h"
#import "DrawPath.h" @interface DrawView() @property(nonatomic,strong) DrawPath* path; // 线的数组
@property(nonatomic,strong) NSMutableArray* paths; @end @implementation DrawView - (void)awakeFromNib{ [self setUp];
} - (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setUp];
}
return self;
} // 重绘UI
- (void)drawRect:(CGRect)rect { for (DrawPath* path in self.paths) { if ([path isKindOfClass:[UIImage class]]) {
// 画图片
UIImage* image = (UIImage*)path;
[image drawInRect:rect];
}else{
// 画线 // 设置画笔颜色
[path.pathColor set]; // 绘制
[path stroke];
}
}
} // 懒加载属性
- (NSMutableArray*)paths{ if (_paths == nil) {
_paths = [NSMutableArray array];
}
return _paths;
} // 重写image属性
- (void)setImage:(UIImage *)image{ _image = image; // 将图片加入到线条数组中
[self.paths addObject:image]; [self setNeedsDisplay];
} #pragma mark - Init // 初始化
- (void)setUp{ // 添加平移手势
UIPanGestureRecognizer* panGes = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGes:)];
[self addGestureRecognizer:panGes]; // 默认值
self.lineWidth = ;
self.pathColor = [UIColor blackColor];
} #pragma mark - Event // 平移事件
- (void)panGes:(UIPanGestureRecognizer*)ges{ // 获取当前点
CGPoint curPoint = [ges locationInView:self]; if (ges.state == UIGestureRecognizerStateBegan) { // 开始移动 // 创建贝塞尔曲线
_path = [[DrawPath alloc]init]; // 设置线条宽度
_path.lineWidth = _lineWidth; // 线条默认颜色
_path.pathColor = _pathColor; // 设置起始点
[_path moveToPoint:curPoint]; [self.paths addObject:_path];
} // 连线
[_path addLineToPoint:curPoint]; // 重绘
[self setNeedsDisplay];
} #pragma mark - Method // 清屏
- (void)clear{ [self.paths removeAllObjects]; [self setNeedsDisplay];
} // 撤销
- (void)undo{ [self.paths removeLastObject]; [self setNeedsDisplay];
} // 橡皮擦
- (void)eraser{ self.pathColor = [UIColor whiteColor]; [self setNeedsDisplay];
} // 保存
- (void)save{ // ---- 截图操作
// 开启上下文
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, ); // 获取当前上下文
CGContextRef context = UIGraphicsGetCurrentContext(); // 渲染图层到上下文
[self.layer renderInContext:context]; // 从上下文中获取图片
UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); // 关闭上下文
UIGraphicsEndImageContext(); // ---- 保存图片
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } // 图片保存方法,必需写这个方法体,不能会保存不了图片
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ // 提示
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"保存成功" message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
[alert show];
} @end

4、接下来就是如果使用这个画板类了,直接上代码吧

//
// ViewController.m
// 画板
//
// Created by xgao on 16/4/13.
// Copyright © 2016年 xgao. All rights reserved.
// #import "ViewController.h"
#import "DrawView.h" @interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate> // 画板
@property (weak, nonatomic) IBOutlet DrawView *drawView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; } #pragma mark - Event // 线条宽度变化
- (IBAction)lineWidthChange:(UISlider*)sender { _drawView.lineWidth = sender.value;
} // 线条颜色变化
- (IBAction)pathColorChange:(UIButton*)sender { _drawView.pathColor = sender.backgroundColor;
} // 清屏
- (IBAction)clearAction:(id)sender { [_drawView clear];
} // 撤销
- (IBAction)undoAction:(id)sender { [_drawView undo];
} // 橡皮擦
- (IBAction)eraserAction:(id)sender { [_drawView eraser];
} // 照片
- (IBAction)pickerPhotoAction:(id)sender { // 照片选择控制器
UIImagePickerController* picVC = [[UIImagePickerController alloc]init];
// 照片源
picVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// 委托
picVC.delegate = self; [self presentViewController:picVC animated:YES completion:nil];
} // 保存
- (IBAction)saveAction:(id)sender { [_drawView save];
} #pragma mark - UIImagePickerControllerDelegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(nullable NSDictionary<NSString *,id> *)editingInfo{ // 设置图片
_drawView.image = image; // 关闭窗口
[self dismissViewControllerAnimated:YES completion:nil];
} @end

到这里就差不多了,这个小功能实现的基本思路与具体代码我都已经放上来了,大家如果还有哪里不清楚的可以留言喔~~










IOS简单画板实现的更多相关文章

  1. iOS 简单工厂模式

    iOS 简单工厂模式 什么是简单工厂模式? 简单工厂模式中定义一个抽象类,抽象类中声明公共的特征及属性,抽象子类继承自抽象类,去实现具体的操作.工厂类根据外界需求,在工厂类中创建对应的抽象子类实例并传 ...

  2. iOS 简单引导界面

    代码地址如下:http://www.demodashi.com/demo/11607.html 前言 现在很多APP在用户第一次用的时候,由于用户可能并不知道其中一些功能点的时候,这个时候就需要我们来 ...

  3. iOS: 为画板App增加 Undo/Redo(撤销/重做)操作

    这个随笔的内容以上一个随笔为基础,(在iOS中实现一个简单的画板),上一个随笔实现了一个简单的画板:   今天我们要为这个画板增加Undo/Redo操作,当画错了一笔,可以撤销它,或者撤销之后后悔了, ...

  4. ios 简单的plist文件读写操作(Document和NSUserDefaults)

    最近遇到ios上文件读写操作的有关知识,记录下来,以便以后查阅,同时分享与大家. 一,简单介绍一下常用的plist文件. 全名是:Property List,属性列表文件,它是一种用来存储串行化后的对 ...

  5. iOS简单快速集成Cordova

    如果你对于什么是Cordova还不了解,可以先移步到我另一个文章:Cordoval在iOS中的运用整理 里面有详细的介绍跟如何搭建Cordova:而本文则是要介绍JiaCordova插件,如果你有一点 ...

  6. iOS 简单获取当前地理坐标

    iOS 获取当前地理坐标        iOS获取当前地理坐标,很简单几句代码,但是如果刚开始不懂,做起来也会也会出现一些问题. 1.导入定位需要用到的库:CoreLocation.framwork ...

  7. iOS开发——高级篇——iOS涂鸦画板效果实现

    一个简单的绘图应用,模仿苹果自带软件备忘录里的涂鸦功能 核心代码 #import "DrawView.h" #import "DrawPath.h" @inte ...

  8. iOS简单音乐实现、React-Native完整项目、仿闲鱼京东列表分页、语音识别、网络加载过度动画等源码

    iOS精选源码 iOS快速入手语音识别.听写.评测.播报 网络加载数据的过渡动画(仿简书网页) iOS 封装跑马灯和轮播效果 crash防护组件,适用常见常用的数组,字典等crash保护 iOS:高仿 ...

  9. iOS简单动画

    知识架构 CALayer 图层类 CABasicAnimation 基础动画 CAKeyFrameAnimation 帧动画 CATransition 转场动画 CAAnimationGroup 动画 ...

随机推荐

  1. asp.net core mvc剖析:处理管道构建

    在启动流程文章中提到,在WebHost类中,通过BuildApplication完成http请求处理管道的构建.在来看一下代码: ...... //这个调用的就是Startup.cs类中的Config ...

  2. 单页应用SPA的路由

    关于单页应用 单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用 ...

  3. html中如何修改选中 用input做的搜索框 的边框颜色

    html中如何修改选中 用input做的搜索框 的边框颜色 如图,当我鼠标选中输入框时,内边框会变成蓝色 我的问题是: 1.如何把蓝色去掉? 2.如何改成别的颜色? 首先感谢 UI设计师提出的需求,解 ...

  4. Unity中的万能对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的万能对象池 本节通过一个简单的射击子弹的示例来介 ...

  5. UE4 RHI与Render模块简解

    UE4中的RHI指的是Render hardware interface,作用像Ogre里的RenderSystem,针对Dx11,Dx12,Opengl等等平台抽象出相同的接口,我们能方便能使用相同 ...

  6. JS高级程序设计学习笔记——继承

    我们知道,在OO语言中,继承可分为接口继承和实现继承.而ECMAScript的函数没有签名,不能实现“接口继承”,只能通过原型链实现“实现继承”. 在学习了各种继承模式之后,简单总结一下各种继承模式的 ...

  7. 【Eclipse】web项目部署新手篇

    本文属于新手篇章,记录了Eclipse中部署web项目的步骤 1 . 添加Tomcat服务器 右键项目属性-->Run as-->Run on server弹出以下界面 点击finish之 ...

  8. C# 知识回顾 - 装箱与拆箱

    装箱与拆箱 目录 生活中的装箱与拆箱 C# 的装箱与拆箱 值类型和引用类型 装箱 拆箱 生活中的装箱与拆箱    我们习惯了在网上购物,这次你想买本编程书 -- <C 语言从入门到放弃> ...

  9. C#语言基础——定义变量、变量赋值、输入输出

    第一部分 了解c# 一.C#的定义及其特点 C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.net的应用而开发的语言.它吸收了c++.Visual basi ...

  10. 【Harmony】概述

      原文来自本人的微信公众号文章  系统工程实验室     引言 基于模型的系统工程(简称MBSE,英文全称Model based System Engineering )的实践至少需要三个维度的支撑 ...