• [iOS UI进阶


    A.需求
    1.超简易画图,只有一种画笔
    2.清屏功能
    3.回退功能
    4.保存功能
    5.使用了cocos2D
     
     
    Image(12)
     
    B.实现方法1
    1.基本界面
    (1)3个按钮:清屏、回退、保存
    (2)绘图view
    Image(13)
     
    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 = 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控件调整线宽
    • 选择颜色
     
    Image(14)
     
    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 @optional
    15 - (void) selectColor:(UIColor *) selectedColor;
    16 
    17 @end
    18 
    19 @interface ColorSelectionView : UIView
    20 
    21 /** 代理 */
    22 @property(nonatomic, strong) id<ColorSelectionViewDelegate> delegate;
    23 
    24 @end
    25  
    26 //
    27 //  ColorSelectionView.m
    28 //  PaintDemo
    29 //
    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 ColorSelectionView
    37 
    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 : UIBezierPath
    12 
    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 @end
    26 
    27 @implementation ViewController
    28 
    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
     
  • 相关阅读:
    一步一步学EF系列二【Fluent API的方式来处理实体与数据表之间的映射关系】
    EntityFramework 6 开篇
    DOS For循环
    mysql中查看所有表、表字段、表注释、字段注释
    灾备还原之gitlab
    JavaScript 实现继承的5种方式
    HBuilder完成webApp入门(5) 实例
    HBuilder完成webApp入门(4) 实例
    HBuilder完成webApp入门(3) 关于webview (转)
    HBuilder完成webApp入门(2)
  • 原文地址:https://www.cnblogs.com/hellovoidworld/p/4216673.html
Copyright © 2020-2023  润新知