ios學記0008-畫板drawingBoard
自己封裝畫板類
前言
這次簡單學習了 CG (Core Graphics 框架)這個二次元框架,我自己簡單使用之後覺得這個基於C語言弄出來的框架挺好用的,就是可能OC語法用久了,有些人會有些不習慣C語言的語法了.沒關係,我相信你學習OC之前肯定已經熟練C語言了,用一用就習慣了.
學習建議
開始今天的正題,註釋我都寫在程式碼中了,很詳細,基本實現了畫板的基礎功能,你完全可以直接把我的 G_DrawingBoard.h & G_DrawingBoard.m 檔案程式碼copy出去直接使用.使用方法我會 paste 到文章的最後.
不過我還是希望通過我的口水話,能夠提高你我的業務能力
//
// G_DrawingBoard.h
// UI_高階_畫板
//
// Created by Gavin Guan on 16/5/26.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import <UIKit/UIKit.h>
#define TEST 1
//這裡值為1時,開啟除錯程式碼段,為0時,反之.
@interface G_DrawingBoard : UIView
@property (retain, nonatomic) NSMutableArray *G_paths; //存每一條路徑
@property (retain, nonatomic) NSMutableArray *G_lineDic;//存每一條路徑的對應資訊
@property (copy, nonatomic) UIColor *G_lineColor; //存當前畫筆顏色
@property (assign, nonatomic) CGFloat G_lineWidth; //存當前畫筆寬度(粗細)
- (void)refreshDisplay; //重新整理畫板檢視的方法
@end
//
// G_DrawingBoard.m
// UI_高階_畫板
//
// Created by Gavin Guan on 16/5/26.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import "G_DrawingBoard.h"
@implementation G_DrawingBoard
//-------------------------------------------
//-------------------------------------------
#pragma mark - init方法 - 程式碼建立方法
- (instancetype)init
{
self = [super init];
if (self) {
//僅僅單指,背景白色,屬性值初始化
self.multipleTouchEnabled = NO; //關閉多點觸控
self.backgroundColor = [UIColor whiteColor];
self.G_paths = [[NSMutableArray alloc] init];
self.G_lineDic = [[NSMutableArray alloc] init];
self.G_lineColor = [UIColor blackColor];
self.G_lineWidth = 3;
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//僅僅單指,背景白色,屬性值初始化
self.multipleTouchEnabled = NO; //關閉多點觸控
self.backgroundColor = [UIColor whiteColor];
self.G_paths = [[NSMutableArray alloc] init];
self.G_lineDic = [[NSMutableArray alloc] init];
self.G_lineColor = [UIColor blackColor];
self.G_lineWidth = 3;
}
return self;
}
//-------------------------------------------
#pragma mark - awakeFromNib方法 - 使用nib或者storyBoard建立方法
-(void)awakeFromNib {
//僅僅單指,背景白色,屬性值初始化
self.multipleTouchEnabled = NO; //關閉多點觸控
self.backgroundColor = [UIColor whiteColor];
self.G_paths = [[NSMutableArray alloc] init];
self.G_lineDic = [[NSMutableArray alloc] init];
self.G_lineColor = [UIColor blackColor];
self.G_lineWidth = 3;
}
//-------------------------------------------
#pragma mark - drawRect方法
//該方法會在檢視初次載入時呼叫,也會在向系統申請重新整理檢視時呼叫
- (void)drawRect:(CGRect)rect {
//以下程式碼會逐個新增路徑(資訊)到繪圖環境
NSMutableArray *arr = self.G_paths;
#if TEST
NSLog(@"arr count = %ld", self.G_paths.count);
#endif
//獲取當前繪製環境 如果你要在檢視上話多個圖形,並且封裝在方法中,那麼每個方法中都需要
//獲取一次context繪圖環境(繪圖上下文),這裡只需獲取一次
CGContextRef context = UIGraphicsGetCurrentContext();
//遊歷 path 陣列
for (int i = 0; i < self.G_paths.count; i++) {
//獲取繪製屬性
NSDictionary *lineDic = self.G_lineDic[i];
UIColor *lineColor = lineDic[@"lineColor"];
CGFloat lineWidth = [lineDic[@"lineWidth"] doubleValue] ;
//設定線段顏色
CGContextSetStrokeColorWithColor(context, lineColor.CGColor);
//設定線條寬度
CGContextSetLineWidth(context, lineWidth);
//設定拐點的樣式
CGContextSetLineJoin(context, kCGLineJoinRound);
//獲取路徑
CGMutablePathRef path = (__bridge CGMutablePathRef)(arr[i]);
//新增路徑到當前繪製環境
CGContextAddPath(context, path);
//繪製路徑
//繪製模式
CGContextDrawPath(context, kCGPathStroke);
//繪製模式這段程式碼的執行機制是這樣的,就像是一個繪製斷點,之前的線條寬度之類的屬性
//如果後面你不修改,那麼就是使用原有的,如果你修改了,就使用修改後的.
//這裡for迴圈結束一次,再次開始的時候,又會從我設定的lineDic中獲取對應的資訊來處
//理下一次繪製時的"畫筆"的屬性,以實現畫板.
}
}
//-------------------------------------------
#pragma mark - touches方法
//手指接觸到螢幕時,呼叫一次,僅一次
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//獲取唯一的觸控物件 -- 開始位置
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [touch locationInView:self];
#if TEST
NSLog(@"當前觸控開始位置(%.2f , %.2f)", locationPoint.x, locationPoint.y);
#endif
//建立可變路徑
CGMutablePathRef path = CGPathCreateMutable();
//路徑移動到初始點 - 如同"畫筆"移動到某一點準備繪製
CGPathMoveToPoint(path, NULL, locationPoint.x, locationPoint.y);
//新增 path 到路徑陣列
[self.G_paths addObject:(__bridge id _Nonnull)(path)];
//儲存 path 資訊 - 當前"畫筆"屬性
NSDictionary *lineDic = @{
@"lineColor" : self.G_lineColor,
@"lineWidth" : [NSNumber numberWithDouble:self.G_lineWidth]
};
[self.G_lineDic addObject:lineDic];
//手動釋放路徑 - 通過create方式建立的CGPathRef一定要free,不然有記憶體洩漏
//CGPathRelease(path);
//我多次通過程式碼實驗,猜測通過橋接方法(如下程式碼)
//[self.G_paths addObject:(__bridge id _Nonnull)(path)];
//新增path時,運作機制類似於retain一次,所以這裡不要free這個path
//會影響到path陣列中的元素path,成為野指標,釋放的方法我寫在了dealloc方法中
}
//僅僅在手指移動時呼叫(超級頻繁)
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//獲取唯一的觸控物件 -- 移動路徑點
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [touch locationInView:self];
#if TEST
NSLog(@"當前觸控移動路徑(%.2f , %.2f)", locationPoint.x, locationPoint.y);
#endif
//移動時,新增 實時點 到路徑
NSArray *arr = self.G_paths;
CGMutablePathRef path = (__bridge CGMutablePathRef)([arr lastObject]);
CGPathAddLineToPoint(path, NULL, locationPoint.x, locationPoint.y);
//重新整理檢視
[self refreshDisplay];
}
//-------------------------------------------
#pragma mark - 重新整理繪製
- (void)refreshDisplay {
//重新整理檢視
[self setNeedsDisplay];
//手動呼叫 drawRect: 方法是無效的,必須通過這個方法通知系統,然後系統自行呼叫 drawRect:
}
//-------------------------------------------
#pragma mark - dealloc方法
-(void)dealloc {
NSMutableArray *arr = self.G_paths;
for (int i = 0; i < self.G_paths.count; i++) {
CGMutablePathRef path = (__bridge CGMutablePathRef)(arr[i]);
CGPathRelease(path); //雖然是ARC模式,但CGPathRef還是要手動釋放的.
}
}
//-------------------------------------------
//-------------------------------------------
@end
下面是使用方法的程式碼簡介 - 寫在任意 viewController.m 中
#pragma mark - 按鈕測試
//撤銷
- (IBAction)repeal:(UIButton *)sender {
//通過移除最後一個Object,重新整理檢視來實現撤銷方法
[self.drawingBoard.G_paths removeLastObject];
[self.drawingBoard.G_lineDic removeLastObject];
[self.drawingBoard refreshDisplay];
}
//變色 & 粗細
- (IBAction)changeColor:(UIButton *)sender {
//這裡僅僅是我自己測試時,使用的程式碼,你可以自己定義多個按鈕
//任意修改 lineColor & lineWidth 屬性 - 修改當前"畫筆"的屬性
if (self.drawingBoard.G_lineColor == [UIColor redColor]) {
self.drawingBoard.G_lineColor = [UIColor blackColor];
self.drawingBoard.G_lineWidth = 3;
} else {
self.drawingBoard.G_lineColor = [UIColor redColor];
self.drawingBoard.G_lineWidth = 10;
}
}
- (IBAction)clearAll:(UIButton *)sender {
//通過移除全部Object,重新整理檢視來實現清屏
[self.drawingBoard.G_paths removeAllObjects];
[self.drawingBoard.G_lineDic removeAllObjects];
[self.drawingBoard refreshDisplay];
}
以上就是這次全部內容,如果你喜歡,就給我點贊吧.╮(╯_╰)╭
我在之後對自己的程式碼又進行了一次封裝優化,同時得到了高人指點再次,有了再次優化的idea,有需要的可以私我,發給你們.
相關文章
- iOS 畫板 塗鴉 答題iOS
- ios開發實現畫板功能iOS
- canvas畫素畫板Canvas
- iOS開發之畫圖板(貝塞爾曲線)iOS
- 前端學習筆記----canvas實現畫板及定製畫筆(畫筆錯位,撤回,粗細,顏色)前端筆記Canvas
- Android 利用 Canvas 畫畫板AndroidCanvas
- Canvas畫板—手機上也可以用的畫板Canvas
- Winform下的畫板ORM
- canvas簡單畫板效果Canvas
- 用kivy學習製作簡易調色畫板appAPP
- Cocos Creator 實現畫板(你畫我猜)
- 自定義view————塗鴉畫板View
- 【JavaScript學習筆記】畫圖JavaScript筆記
- canvas小畫板--(1)平滑曲線Canvas
- canvas小畫板——(3)筆鋒效果Canvas
- java,製作簡易畫圖板Java
- 用canvas畫一個七竅板Canvas
- 畫PCB板時的注意事項
- iOS 邊學邊記iOS
- iOS動畫效果合集、飛吧企鵝遊戲、換膚方案、畫板、文字效果等原始碼iOS動畫遊戲原始碼
- javax.swing.JPanel畫板練習Java
- 仿Windows畫板噴漆筆刷效果Windows
- PowerBuilder DataWindow畫板的更新特性詳解UI
- iOS Block學習筆記iOSBloC筆記
- iOS KVC學習記錄iOS
- iOS KVO學習記錄iOS
- iOS GCD學習記錄iOSGC
- iOS Runloop學習筆記iOSOOP筆記
- 專業的數學教學軟體:幾何畫板Sketchpad Mac中文版Mac
- win10畫板調整大小為A4怎麼設定_win10畫板如何調整大小Win10
- 華碩主機板升級bios教程 華碩主機板如何升級BIOS?iOS
- 幾何畫板中文免費版5.06
- Vue學習筆記 —— axiosVue筆記iOS
- Axios用法–學習筆記iOS筆記
- iOS runtime學習筆記iOS筆記
- iOS 屬性學習筆記iOS筆記
- iOS指標學習筆記iOS指標筆記
- Vue學習筆記(二)------axios學習Vue筆記iOS