利用CGMutablePathRef制作画板涂鸦
生活随笔
收集整理的這篇文章主要介紹了
利用CGMutablePathRef制作画板涂鸦
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
效果圖:
:
具體代碼如下:
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. }@endpenview畫板類的penview.h
#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;@endpenview畫板類的penview.m 大部分功能都是在這里實現
#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 = @[@"顏色",@"線寬",@"橡皮",@"撤銷",@"清屏"];//按鈕的frameCGFloat 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?
轉載于:https://www.cnblogs.com/wzh521/p/4820207.html
總結
以上是生活随笔為你收集整理的利用CGMutablePathRef制作画板涂鸦的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 引用与指针的异同-基础篇
- 下一篇: iOS: 转载CoreData数据库框架