首页 > 代码库 > [iOS UI进阶 - 4.0] 涂鸦app Demo
[iOS UI进阶 - 4.0] 涂鸦app Demo
A.需求
1.超简易画图,只有一种画笔
2.清屏功能
3.回退功能
4.保存功能
5.使用了cocos2D
code source: https://github.com/hellovoidworld/PaintDemo
B.实现方法1
1.基本界面
(1)3个按钮:清屏、回退、保存
(2)绘图view
2.画线
(1)使用数组存储绘图点:存储一条线的数组、存储所有线的总数组
(2)在touch的开始、拖曳、结束记录触摸位置,触发重绘
3.清屏
删除总数组
4.回退
删除最后画的一条线:删除相应数组
5.保存到相册
使用”截图”功能,保存绘图view
1 // 2 // PaintView.m 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/10. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "PaintView.h" 10 #import "UIImage+Extension.h" 11 12 @interface PaintView() 13 14 @end 15 16 @implementation PaintView 17 18 - (NSMutableArray *)lines { 19 if (nil == _lines) { 20 _lines = [NSMutableArray array]; 21 } 22 return _lines; 23 } 24 25 #pragma mark - 触摸事件 26 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 27 UITouch *touch = [touches anyObject]; 28 CGPoint startLocation = [touch locationInView:touch.view]; 29 30 // 开启一条新的线 31 NSMutableArray *points = [NSMutableArray array]; 32 // 存储点信息到线上 33 [points addObject:[NSValue valueWithCGPoint:startLocation]]; 34 // 存储到线组上 35 [self.lines addObject:points]; 36 37 // 重绘 38 [self setNeedsDisplay]; 39 } 40 41 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 42 UITouch *touch = [touches anyObject]; 43 CGPoint location = [touch locationInView:touch.view]; 44 45 // 拿到正在画的线 46 NSMutableArray *points = [self.lines lastObject]; 47 // 添加点信息 48 [points addObject:[NSValue valueWithCGPoint:location]]; 49 50 // 重绘 51 [self setNeedsDisplay]; 52 } 53 54 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 55 // 停止拖曳的逻辑其实和拖曳中是一样的 56 [self touchesMoved:touches withEvent:event]; 57 } 58 59 #pragma mark - 绘图方法 60 /** 绘图 */ 61 - (void)drawRect:(CGRect)rect { 62 CGContextRef ctx = UIGraphicsGetCurrentContext(); 63 64 // 遍历线组,把所有线画出来 65 for (NSArray *line in self.lines) { 66 for (int i=0; i<line.count; i++) { 67 NSValue *pointValue =http://www.mamicode.com/ line[i]; 68 CGPoint point = [pointValue CGPointValue]; 69 70 // 如果是线的第一个点,要先移动画笔到那个点 71 if (0 == i) { 72 CGContextMoveToPoint(ctx, point.x, point.y); 73 } else { 74 CGContextAddLineToPoint(ctx, point.x, point.y); 75 } 76 } 77 } 78 79 // 设置线宽、线头样式、线转折样式 80 CGContextSetLineWidth(ctx, 5); 81 CGContextSetLineCap(ctx, kCGLineCapRound); 82 CGContextSetLineJoin(ctx, kCGLineJoinRound); 83 84 // 渲染 85 CGContextStrokePath(ctx); 86 } 87 88 #pragma mark - view操作方法 89 /** 回退 */ 90 - (void)rollback { 91 [self.lines removeLastObject]; 92 [self setNeedsDisplay]; 93 } 94 95 /** 清屏 */ 96 - (void)clearScreen { 97 [self.lines removeAllObjects]; 98 [self setNeedsDisplay]; 99 }100 101 /** 保存 */102 - (void)save {103 // 1.获取图片104 UIImage *image = [UIImage imageOfView:self];105 106 // 2.保存图片到相册107 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);108 }109 110 /** 保存图片后激发事件111 * 这是文档推荐的方法112 */113 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {114 if (error) {115 NSLog(@"保存失败");116 } else {117 NSLog(@"保存成功");118 }119 }120 121 @end
1 // 2 // UIImage+Extension.m 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/11. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "UIImage+Extension.h"10 11 @implementation UIImage(Extension)12 13 + (UIImage *) imageOfView:(UIView *) view {14 // 1.开启图片上下文15 UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);16 17 // 2.将view的layer渲染到上下文18 [view.layer renderInContext:UIGraphicsGetCurrentContext()];19 20 // 3.获取上下文中的图片21 UIImage *image = UIGraphicsGetImageFromCurrentImageContext();22 23 // 4.关闭图片上下文24 UIGraphicsEndImageContext();25 26 return image;27 }28 29 @end
C.实现方法2
1.基本界面和方法1一样
2.画线
(1)使用贝塞尔路径UIBezierPath,一条线就是一个UIBezierPath对象
(2)同样使用数组来存储UIBezierPath对象
3.清屏、回退、保存和方法1一样
1 // 2 // BezierPaintView.m 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/11. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "BezierPaintView.h" 10 #import "UIImage+Extension.h" 11 12 @implementation BezierPaintView 13 14 - (NSMutableArray *)lines { 15 if (nil == _lines) { 16 _lines = [NSMutableArray array]; 17 } 18 return _lines; 19 } 20 21 #pragma mark - 触摸事件 22 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 23 UITouch *touch = [touches anyObject]; 24 CGPoint startLocation = [touch locationInView:touch.view]; 25 26 // 新建一条Bezier线 27 UIBezierPath *path = [UIBezierPath bezierPath]; 28 [path setLineWidth:5.0]; 29 [path setLineCapStyle:kCGLineCapRound]; 30 [path setLineJoinStyle:kCGLineJoinRound]; 31 32 // 移动到始点 33 [path moveToPoint:startLocation]; 34 // 添加Bezier线到数组 35 [self.lines addObject:path]; 36 37 // 重绘 38 [self setNeedsDisplay]; 39 } 40 41 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 42 UITouch *touch = [touches anyObject]; 43 CGPoint location = [touch locationInView:touch.view]; 44 45 // 获得正在画的线 46 UIBezierPath *path = [self.lines lastObject]; 47 // 画线-添加点信息 48 [path addLineToPoint:location]; 49 50 // 重绘 51 [self setNeedsDisplay]; 52 } 53 54 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 55 // 停止拖曳的逻辑其实和拖曳中是一样的 56 [self touchesMoved:touches withEvent:event]; 57 } 58 59 #pragma mark - 绘图方法 60 /** 绘图 */ 61 - (void)drawRect:(CGRect)rect { 62 63 // 画出所有的线 64 for (UIBezierPath *path in self.lines) { 65 // 渲染 66 [path stroke]; 67 } 68 69 } 70 71 #pragma mark - view操作方法 72 /** 回退 */ 73 - (void)rollback { 74 [self.lines removeLastObject]; 75 [self setNeedsDisplay]; 76 } 77 78 /** 清屏 */ 79 - (void)clearScreen { 80 [self.lines removeAllObjects]; 81 [self setNeedsDisplay]; 82 } 83 84 /** 保存 */ 85 - (void)save { 86 // 1.获取图片 87 UIImage *image = [UIImage imageOfView:self]; 88 89 // 2.保存图片到相册 90 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 91 } 92 93 /** 保存图片后激发事件 94 * 这是文档推荐的方法 95 */ 96 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { 97 if (error) { 98 NSLog(@"保存失败"); 99 } else {100 NSLog(@"保存成功");101 }102 }103 104 @end
D.附加功能
- slider控件调整线宽
- 选择颜色
1.slider调整线宽
(1)使用slider控件
(2)通过slider的valueChange事件调用方法设置线宽
2.选择颜色
(1)创建一个“色块”类
- 使用UIView作为色块
- 自定义一个继承UIView的类,作为色块class,给色块UIView加上点击事件
- 给色块UIView创建一个颜色属性和代理协议,代理是ViewController;创建一个点击代理事件方法
1 // 2 // ColorSelectionView.h 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/11. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h>10 11 @protocol ColorSelectionViewDelegate <NSObject>12 13 /** “色块”点击代理方法 */14 @optional15 - (void) selectColor:(UIColor *) selectedColor;16 17 @end18 19 @interface ColorSelectionView : UIView20 21 /** 代理 */22 @property(nonatomic, strong) id<ColorSelectionViewDelegate> delegate;23 24 @end25 26 //27 // ColorSelectionView.m28 // PaintDemo29 //30 // Created by hellovoidworld on 15/1/11.31 // Copyright (c) 2015年 hellovoidworld. All rights reserved.32 //33 34 #import "ColorSelectionView.h"35 36 @implementation ColorSelectionView37 38 - (void)awakeFromNib {39 // 给UIView设置点击事件40 UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(colorClicked)];41 [self addGestureRecognizer:tapGesture];42 }43 44 /** “色块”点击事件 */45 - (void) colorClicked {46 [self.delegate selectColor:self.backgroundColor];47 }48 49 @end
(2)自定义一个继承UIBezierPath的类,增加一个线颜色的属性
1 // 2 // HVWBezierPath.h 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/11. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h>10 11 @interface HVWBezierPath : UIBezierPath12 13 /** 颜色 */14 @property(nonatomic, strong) UIColor *color;15 16 @end
(3)ViewController代理“色块”的点击事件
- 拖入所有“色块”对象到ViewController,设置代理
- 遵守“色块”协议,实现代理方法
1 // 2 // ViewController.m 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/10. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "ViewController.h"10 #import "BezierPaintView.h"11 #import "ColorSelectionView.h"12 13 @interface ViewController () <ColorSelectionViewDelegate>14 15 @property (weak, nonatomic) IBOutlet BezierPaintView *paintView;16 17 /** 颜色选择集合 */18 @property (strong, nonatomic) IBOutletCollection(ColorSelectionView) NSArray *colorSelection;19 20 - (IBAction)rollback;21 - (IBAction)clearScreen;22 - (IBAction)save;23 - (IBAction)lineWidthChange:(UISlider *)sender;24 25 @end26 27 @implementation ViewController28 29 - (void)viewDidLoad {30 [super viewDidLoad];31 // Do any additional setup after loading the view, typically from a nib.32 33 // 设置颜色选择器的代理34 for (ColorSelectionView *colorView in self.colorSelection) {35 colorView.delegate = self;36 }37 }38 39 - (void)didReceiveMemoryWarning {40 [super didReceiveMemoryWarning];41 // Dispose of any resources that can be recreated.42 }43 44 /** 回退 */45 - (IBAction)rollback {46 [self.paintView rollback];47 }48 49 /** 清屏 */50 - (IBAction)clearScreen {51 [self.paintView clearScreen];52 }53 54 /** 保存 */55 - (IBAction)save {56 [self.paintView save];57 }58 59 /** 改变线粗 */60 - (IBAction)lineWidthChange:(UISlider *)sender {61 self.paintView.lineWidth = sender.value;62 }63 64 #pragma mark - ColorSelectionViewDelegate 代理方法65 - (void) selectColor:(UIColor *) selectedColor {66 self.paintView.lineColor = selectedColor;67 }
@end
(4)“画板”在开始画一条线的时候(触摸开始),设置线宽和颜色
1 // 2 // BezierPaintView.m 3 // PaintDemo 4 // 5 // Created by hellovoidworld on 15/1/11. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "BezierPaintView.h" 10 #import "UIImage+Extension.h" 11 #import "HVWBezierPath.h" 12 13 @interface BezierPaintView() 14 15 @end 16 17 @implementation BezierPaintView 18 19 - (NSMutableArray *)lines { 20 if (nil == _lines) { 21 _lines = [NSMutableArray array]; 22 } 23 return _lines; 24 } 25 26 #pragma mark - 触摸事件 27 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 28 UITouch *touch = [touches anyObject]; 29 CGPoint startLocation = [touch locationInView:touch.view]; 30 31 // 新建一条Bezier线 32 HVWBezierPath *path = [[HVWBezierPath alloc] init]; 33 34 // 配置线粗 35 if (self.lineWidth) { 36 [path setLineWidth:self.lineWidth]; 37 } 38 39 // 配置线色 40 if (self.lineColor) { 41 path.color = self.lineColor; 42 } 43 44 [path setLineCapStyle:kCGLineCapRound]; 45 [path setLineJoinStyle:kCGLineJoinRound]; 46 47 // 移动到始点 48 [path moveToPoint:startLocation]; 49 // 添加Bezier线到数组 50 [self.lines addObject:path]; 51 52 // 重绘 53 [self setNeedsDisplay]; 54 } 55 56 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 57 UITouch *touch = [touches anyObject]; 58 CGPoint location = [touch locationInView:touch.view]; 59 60 // 获得正在画的线 61 HVWBezierPath *path = [self.lines lastObject]; 62 // 画线-添加点信息 63 [path addLineToPoint:location]; 64 65 // 重绘 66 [self setNeedsDisplay]; 67 } 68 69 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 70 // 停止拖曳的逻辑其实和拖曳中是一样的 71 [self touchesMoved:touches withEvent:event]; 72 } 73 74 #pragma mark - 绘图方法 75 /** 绘图 */ 76 - (void)drawRect:(CGRect)rect { 77 78 // 画出所有的线 79 for (HVWBezierPath *path in self.lines) { 80 81 // 设置颜色 82 if (path.color) { 83 [path.color set]; 84 } 85 86 // 渲染 87 [path stroke]; 88 } 89 90 } 91 92 #pragma mark - view操作方法 93 /** 回退 */ 94 - (void)rollback { 95 [self.lines removeLastObject]; 96 [self setNeedsDisplay]; 97 } 98 99 /** 清屏 */100 - (void)clearScreen {101 [self.lines removeAllObjects];102 [self setNeedsDisplay];103 }104 105 /** 保存 */106 - (void)save {107 // 1.获取图片108 UIImage *image = [UIImage imageOfView:self];109 110 // 2.保存图片到相册111 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);112 }113 114 /** 保存图片后激发事件115 * 这是文档推荐的方法116 */117 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {118 if (error) {119 NSLog(@"保存失败");120 } else {121 NSLog(@"保存成功");122 }123 }124 125 126 @end
[iOS UI进阶 - 4.0] 涂鸦app Demo
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。