效果圖:數組
:安全
具體代碼以下:ide
ViewControl:工具
#import "ViewController.h" #import "PenView.h" #import "ToolView.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //建立畫板 PenView *penView = [[PenView alloc]initWithFrame:[UIScreen mainScreen].bounds]; penView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:penView]; //建立工具欄 CGFloat width = [UIScreen mainScreen].bounds.size.width; ToolView *toolView = [[ToolView alloc]initWithFrame:CGRectMake(0, 20, width, 110)]; toolView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:toolView]; //block的實現 [toolView addColorBlock:^(UIColor *color) { penView.color = color; } withLineWidth:^(CGFloat width) { penView.lineWidth = width; } andMyBlock:^{ penView.color = [UIColor whiteColor]; penView.lineWidth = 20; } andMyBlock:^{ [penView back]; } andMyBlock:^{ [penView clear]; }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
penview畫板類的penview.hatom
#import <UIKit/UIKit.h> @interface PenView : UIView { CGMutablePathRef path; NSMutableArray *pathArr; } @property (nonatomic, strong)UIColor *color; @property (nonatomic, assign)CGFloat lineWidth; - (void)back; - (void)clear; @end
penview畫板類的penview.m 大部分功能都是在這裏實現spa
#import "PenView.h" #import "PathModel.h" @implementation PenView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { //給初始值 _color = [UIColor blackColor]; _lineWidth = 2.0; } return self;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //獲取手指開始點擊屏幕的位置 UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:touch.view]; //建立一個全局的路徑,注意這裏咱們用到了create,因此在下面必定要記得釋放 path = CGPathCreateMutable(); //起始點 CGPathMoveToPoint(path, NULL, point.x, point.y); //刷新重繪 [self setNeedsDisplay]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:touch.view]; //畫線 CGPathAddLineToPoint(path, NULL, point.x, point.y); [self setNeedsDisplay]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //爲了保證 不重複建立 if (pathArr == nil) { pathArr = [[NSMutableArray alloc]init]; } //創建的model用來保存咱們所畫的每條線段的粗細,顏色,等 PathModel *model = [[PathModel alloc]init]; model.path = path; model.color = _color; model.width = _lineWidth; //將model對象放入數組 [pathArr addObject:model]; //安全釋放 CGPathRelease(path); //將指針對象清空 path = nil; } //畫 - (void)drawRect:(CGRect)rect { //根據path,劃線 if (path != nil) { //得到上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //添加路徑到上下文 CGContextAddPath(ctx, path); //設置屬性 [_color set]; CGContextSetLineWidth(ctx, _lineWidth); //畫 CGContextDrawPath(ctx, kCGPathStroke); } //咱們用model保存的每一條路徑。爲了確保以前畫的線段都存在。(你畫第二條線時,第一條線的路徑和顏色,粗細保存在model.保證你畫第二條線時,第一條線不會消失) if (pathArr != nil){ for (int i = 0; i < pathArr.count; i ++) { //建立模型 PathModel *model = [pathArr objectAtIndex:i]; //去除模型中的數據 CGMutablePathRef pa = model.path; UIColor *color = model.color; CGFloat width = model.width; //獲取上下文,這裏的上下文與前面獲取的爲同一個 CGContextRef ctx = UIGraphicsGetCurrentContext(); //添加路徑到上下文 CGContextAddPath(ctx, pa); //設置顏色等屬性 [color set]; CGContextSetLineWidth(ctx, width); //畫 CGContextDrawPath(ctx, kCGPathStroke); } } } //撤銷,說白了就是刪除數組裏的最後一個model - (void)back { [pathArr removeLastObject]; [self setNeedsDisplay]; } //清空 - (void)clear { [pathArr removeAllObjects]; [self setNeedsDisplay]; } @end //建立model類 #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface PathModel : NSObject @property (nonatomic, assign)CGMutablePathRef path; @property (nonatomic, strong)UIColor *color; @property (nonatomic, assign)CGFloat width; @end //建立工具欄的.h文件 #import <UIKit/UIKit.h> @class seleButton; typedef void(^ColorBlock)(UIColor *color); typedef void(^LineWidth)(CGFloat width); typedef void(^MyBlock)(void); @interface ToolView : UIView { seleButton *_lastButton; UIView *_colorView; UIView *_lineView; NSArray *_lineArr; ColorBlock _colorBlock; LineWidth _lineWidth; MyBlock _block1; MyBlock _block2; MyBlock _block3; } //set 方法 只不過這個方法參數有點多。 - (void)addColorBlock:(ColorBlock)colorBlock withLineWidth:(LineWidth)lineWidth andMyBlock:(MyBlock)block1 andMyBlock:(MyBlock)block2 andMyBlock:(MyBlock)block3; @end //建立工具欄的.m文件 #import "ToolView.h" #import "seleButton.h" #define KScreenWidth [UIScreen mainScreen].bounds.size.width @implementation ToolView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { //建立選擇按鈕 [self _initSeleter]; //建立選擇顏色的視圖 [self _initColor]; //建立選擇線寬的視圖 [self _initLineWidthView]; } return self; } //set方法 - (void)addColorBlock:(ColorBlock)colorBlock withLineWidth:(LineWidth)lineWidth andMyBlock:(MyBlock)block1 andMyBlock:(MyBlock)block2 andMyBlock:(MyBlock)block3{ _colorBlock = colorBlock; _lineWidth = lineWidth; _block1 = block1; _block2 = block2; _block3 = block3; } - (void)drawRect:(CGRect)rect { // Drawing code } //建立選擇按鈕 - (void)_initSeleter { NSArray *titleArr = @[@"顏色",@"線寬",@"橡皮",@"撤銷",@"清屏"]; //按鈕的frame CGFloat width = KScreenWidth / 5.0; for (int i = 0; i < 5; i ++) { seleButton *selectButton = [[seleButton alloc]initWithFrame:CGRectMake(width * i, 0, width, 40)]; selectButton.title = titleArr[i]; selectButton.backgroundColor = [UIColor clearColor]; selectButton.tag = 100 + i; [selectButton addTarget:self action:@selector(selectButtonAction:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:selectButton]; } } - (void)selectButtonAction:(seleButton *)button { //取消前一次點擊的按鈕 _lastButton.isSeleter = NO; //設置選中的標示 button.isSeleter = YES; //記錄選中的按鈕 _lastButton = button; switch (button.tag) { case 100: //選擇顏色面板 _colorView.hidden = NO; _lineView.hidden = YES; break; case 101: //選擇線寬面板 _colorView.hidden = YES; _lineView.hidden = NO; break; case 102: //選擇橡皮面板 if (_block1) { _block1(); } break; case 103: //選擇撤銷 if (_block2) { _block2(); } break; case 104: //選擇清屏 if (_block3) { _block3(); } break; default: break; } } //建立顏色視圖 - (void)_initColor { //建立顏色數組 NSArray *colorArray = @[ [UIColor grayColor], [UIColor redColor], [UIColor greenColor], [UIColor blueColor], [UIColor yellowColor], [UIColor magentaColor], [UIColor orangeColor], [UIColor purpleColor], [UIColor blackColor] ]; //建立顯示顏色的fu視圖 _colorView = [[UIView alloc]initWithFrame:CGRectMake(0, 40, KScreenWidth, 65)]; _colorView.hidden = YES; _colorView.backgroundColor = [UIColor clearColor]; [self addSubview:_colorView]; //建立顯示顏色的zi視圖 CGFloat width = KScreenWidth / 9.0; for (int i = 0; i < colorArray.count; i ++) { UIControl *control = [[UIControl alloc]initWithFrame:CGRectMake(width * i, 5, width - 5, 65 - 10)]; control.backgroundColor = colorArray[i]; [control addTarget:self action:@selector(colorAction:) forControlEvents:UIControlEventTouchUpInside]; [_colorView addSubview:control]; } } - (void)colorAction:(UIControl *)control { UIColor *color = control.backgroundColor; //block的回調 _colorBlock(color); } //建立線寬視圖 - (void)_initLineWidthView { _lineView = [[UIView alloc]initWithFrame:CGRectMake(0, 40, KScreenWidth, 65)]; _lineView.hidden = YES; _lineView.backgroundColor = [UIColor clearColor]; [self addSubview:_lineView]; _lineArr = @[@1,@3,@5,@8,@10,@15,@20]; CGFloat width = KScreenWidth / 7.0; for (int i = 0; i < _lineArr.count; i ++) { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.tag = i; NSString *name = [NSString stringWithFormat:@"%@點",_lineArr[i]]; [button setTitle:name forState:UIControlStateNormal]; button.frame = CGRectMake(width * i, 5, width - 5, 65 - 10); [button addTarget:self action:@selector(lineWidthAction:) forControlEvents:UIControlEventTouchUpInside]; [_lineView addSubview:button]; } } - (void)lineWidthAction:(UIButton *)button { NSNumber *number = _lineArr[button.tag]; NSLog(@"%@",number); CGFloat flo = [number floatValue]; //block的回調 _lineWidth(flo); } @end 按鈕的子類化建立 新建一個類繼承子UIControl #import <UIKit/UIKit.h> @interface seleButton : UIControl @property (nonatomic, copy)NSString *title; @property (nonatomic, assign)BOOL isSeleter; @property (nonatomic, strong)UIFont *font; @end .m #import "seleButton.h" @implementation seleButton - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _title = @"默認標題"; _isSeleter = NO; _font = [UIFont systemFontOfSize:17]; } return self; } - (void)drawRect:(CGRect)rect { //繪製文字 NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; //設置文字居中 style.alignment = NSTextAlignmentCenter; NSDictionary *dic = @{ NSFontAttributeName:_font, NSParagraphStyleAttributeName:style }; //花文字 rect.origin.y += 10; [_title drawInRect:rect withAttributes:dic]; //畫紅色選中線條 if (_isSeleter){ CGRect frame = CGRectMake(0, CGRectGetHeight(rect) - 2, CGRectGetWidth(rect), 2); [[UIColor redColor]set]; UIRectFill(frame); } } - (void)setTitle:(NSString *)title { _title = title; [self setNeedsDisplay]; } - (void)setFont:(UIFont *)font { _font = font; [self setNeedsDisplay]; } - (void)setIsSeleter:(BOOL)isSeleter { _isSeleter = isSeleter; [self setNeedsDisplay]; } @end