ios開發(fā)實(shí)現(xiàn)畫板功能

最近看了一些網(wǎng)上的畫板demo,這些demo的實(shí)現(xiàn)方式基本上是使用CGContextRef或者UIBezierPath實(shí)現(xiàn),但是基本上都存在一個比較嚴(yán)重的bug凌受,在使用擦除功能的時候基本上都是直接將畫板的顏色改為背景的顏色赌厅,那么當(dāng)背景的是一張圖片或者背景并不是單一顏色而是多種顏色時,擦除功能就會失效砂缩。本demo文章將解決這樣一個問題。按照國際慣例先上圖。

1.gif

demo主要使用CGContextRef實(shí)現(xiàn)挟冠,擦除功能使用kCGBlendModeDestinationIn和clearColor聯(lián)合使用實(shí)現(xiàn)。
1镣屹、新建DWStroke類存儲CGContextRef信息
DWStroke.h

#import <UIKit/UIKit.h>

typedef struct CGPath *CGMutablePathRef;
typedef enum CGBlendMode CGBlendMode;

@interface DWStroke : NSObject

@property (nonatomic) CGMutablePathRef path;
@property (nonatomic, assign) CGBlendMode blendMode;
@property (nonatomic, assign) CGFloat strokeWidth;
@property (nonatomic, strong) UIColor *lineColor;
- (void)strokeWithContext:(CGContextRef)context;
@end

DWStroke.m

- (void)strokeWithContext:(CGContextRef)context {
    CGContextSetStrokeColorWithColor(context, [_lineColor CGColor]);
    CGContextSetLineWidth(context, _strokeWidth);
    CGContextSetBlendMode(context, _blendMode);
    CGContextBeginPath(context);
    CGContextAddPath(context, _path);
    CGContextStrokePath(context);
}

2圃郊、畫板
DrawTouchPointView.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface DrawTouchPointView : UIView
/** 清屏 */
- (void)clearScreen;
/** 撤消操作 */
- (void)revokeScreen;
/** 擦除 */
- (void)eraseSreen;
/** 設(shè)置畫筆顏色 */
- (void)setStrokeColor:(UIColor *)lineColor;
/** 設(shè)置畫筆大小 */
- (void)setStrokeWidth:(CGFloat)lineWidth;
@end

DrawTouchPointView.m

@interface DrawTouchPointView () {
     CGMutablePathRef currentPath;//路徑
}
//是否擦除
@property (nonatomic, assign) BOOL isEarse;
//存儲所有的路徑
@property (nonatomic, strong) NSMutableArray *stroks;
//畫筆顏色
@property (nonatomic, strong) UIColor *lineColor;
//線條寬度
@property (nonatomic, assign) CGFloat lineWidth;
@end

初始化 ,背景顏色必須為[UIColor clearColor]

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _stroks = [[NSMutableArray alloc] initWithCapacity:1];
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

當(dāng)用戶點(diǎn)擊畫板存儲路徑的基本信息女蜈,并畫起始點(diǎn)持舆,根據(jù)使用擦除來設(shè)置blendMode屬性和畫筆的寬度色瘩,如果是擦除則blendMode = kCGBlendModeDestinationIn,畫筆的大小為20逸寓,畫筆顏色為[UIColor clearColor]

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    currentPath = CGPathCreateMutable();
    DWStroke *stroke = [[DWStroke alloc] init];
    stroke.path = currentPath;
    stroke.blendMode = _isEarse ? kCGBlendModeDestinationIn : kCGBlendModeNormal;
    stroke.strokeWidth = _isEarse ? 20.0 : _lineWidth;
    stroke.lineColor = _isEarse ? [UIColor clearColor] : _lineColor;
    [_stroks addObject:stroke];
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
//    CGAffineTransform transform = CGAffineTransformMakeTranslation(0, 0);
//    CGPathAddArc(currentPath, &transform, point.x, point.y, _lineWidth/2.0, 0, 2*M_PI, 1);
    CGPathMoveToPoint(currentPath, NULL, point.x, point.y);
//    [self setNeedsDisplay];
}

開始移動居兆, setNeedsDisplay 系統(tǒng)自動調(diào)用- (void)drawRect:(CGRect)rect

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    CGPathAddLineToPoint(currentPath, NULL, point.x, point.y);
    [self setNeedsDisplay];
}

在- (void)drawRect:(CGRect)rect中畫圖

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    for (DWStroke *stroke in _stroks) {
        [stroke strokeWithContext:context];
    }
}

清屏功能主要是移除數(shù)組中所有的路徑并調(diào)用[self setNeedsDisplay]、設(shè)置_isEarse = NO
撤消功能主要是移除數(shù)組中最后一個對象并調(diào)用[self setNeedsDisplay]竹伸、設(shè)置_isEarse = NO
擦除功能只需修改isEarse屬性為YES
畫筆功能修改lineColor屬性并設(shè)置_isEarse = NO
畫筆大小功能修改strokeWidth屬性并設(shè)置_isEarse = NO

/** 清屏 */
- (void)clearScreen {
    _isEarse = NO;
    [_stroks removeAllObjects];
    [self setNeedsDisplay];
}

/** 撤消操作 */
- (void)revokeScreen {
    _isEarse = NO;
    [_stroks removeLastObject];
    [self setNeedsDisplay];
}

/** 擦除 */
- (void)eraseSreen {
    self.isEarse = YES;
}
/** 設(shè)置畫筆顏色 */
- (void)setStrokeColor:(UIColor *)lineColor {
    _isEarse = NO;
    self.lineColor = lineColor;
//    [self setNeedsDisplay];
}
/** 設(shè)置畫筆大小 */
- (void)setStrokeWidth:(CGFloat)lineWidth {
    _isEarse = NO;
    self.lineWidth = lineWidth;
}
- (void)dealloc {
    CGPathRelease(currentPath);
}

打完收工泥栖,有什么問題歡迎指出!demo:http://code.cocoachina.com/view/135225
https://github.com/wuzaozhou/iOSDrawingBoard

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勋篓,一起剝皮案震驚了整個濱河市吧享,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌譬嚣,老刑警劉巖钢颂,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拜银,居然都是意外死亡殊鞭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門尼桶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來操灿,“玉大人,你說我怎么就攤上這事泵督≈貉危” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵小腊,是天一觀的道長谤碳。 經(jīng)常有香客問我,道長溢豆,這世上最難降的妖魔是什么蜒简? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮漩仙,結(jié)果婚禮上搓茬,老公的妹妹穿的比我還像新娘。我一直安慰自己队他,他們只是感情好卷仑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著麸折,像睡著了一般锡凝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垢啼,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天窜锯,我揣著相機(jī)與錄音张肾,去河邊找鬼。 笑死锚扎,一個胖子當(dāng)著我的面吹牛吞瞪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驾孔,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼芍秆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了翠勉?” 一聲冷哼從身側(cè)響起妖啥,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎对碌,沒想到半個月后迹栓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俭缓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酥郭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片华坦。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖不从,靈堂內(nèi)的尸體忽然破棺而出惜姐,到底是詐尸還是另有隱情,我是刑警寧澤椿息,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布歹袁,位于F島的核電站,受9級特大地震影響寝优,放射性物質(zhì)發(fā)生泄漏条舔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一乏矾、第九天 我趴在偏房一處隱蔽的房頂上張望孟抗。 院中可真熱鬧,春花似錦钻心、人聲如沸凄硼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摊沉。三九已至,卻和暖如春痒给,著一層夾襖步出監(jiān)牢的瞬間说墨,已是汗流浹背骏全。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婉刀,地道東北人吟温。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像突颊,于是被迫代替她去往敵國和親鲁豪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 由于項(xiàng)目需求需要用到一個畫板功能,需要這個畫板可以實(shí)時的畫律秃,并且需要保存畫板點(diǎn)集合從一端發(fā)送給另一端 達(dá)到一個實(shí)時...
    踏遍青山閱讀 13,735評論 22 49
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,513評論 25 707
  • 朋友圈爬橡,是一個誰都可以抒發(fā)情感的空間。有發(fā)送者棒动,有閱覽者糙申,形成了一個不用言語交流的方式。 許多人船惨,起床柜裸、吃飯、閑暇...
    文顛閱讀 572評論 0 0
  • 懂愛會愛做教育粱锐,懂教會教做教學(xué) 第三屆“潤木名師”教育教學(xué)系列培訓(xùn)
    潤木澤林閱讀 92評論 0 0
  • 固執(zhí)的我疙挺,做了固執(zhí)的決定。 以為逃離了自己厭惡了二十年的城市就可以重新開始怜浅。 天真的認(rèn)為只有離開自己的人生才有轉(zhuǎn)機(jī)...
    細(xì)細(xì)噠噠閱讀 164評論 0 1