iOS之簡筆畫

最近是有些懶了,本計劃一周一篇文章的,現(xiàn)在都變成兩周一篇了,需要反省一下。。。

寫這篇文章是因為有一次看到說現(xiàn)在的程序員,連基本的繪圖都不會,所以就和大家一起學學基本繪圖吧。今天說的是繪制一些基本圖形,就一些圓啊,三角啊什么的,都比較簡單。

    CGContextRef context = UIGraphicsGetCurrentContext();//獲取畫布
    CGContextSetRGBStrokeColor(context, 1, 1, 0, 1.0);//畫筆的顏色
    CGContextSetLineWidth(context, 8.0);//畫筆的粗細
    CGContextAddArc(context, 80, 30, 15, 0, 2 * M_PI, 0);//x,y是圓點坐標,radius是半徑,startAngle是開始的弧度,endAngle是結束的弧度,clockwise是是否為逆時針(1是0否)
    CGContextDrawPath(context, kCGPathStroke);//完成路徑
帶邊框的圓
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);//設置填充顏色
    CGContextSetLineWidth(context, 3.0);//畫筆的粗細
    CGContextAddArc(context, 130, 30, 15, 0, 2 * M_PI, 0);//添加一個圓
    CGContextDrawPath(context, kCGPathFillStroke);//繪制路徑并填充
太極圖
CGContextAddArc(context, 190, 30, 15, M_PI_2, 1.5 * M_PI, 0);
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillPath(context);
    CGContextStrokePath(context);
    
    CGContextAddArc(context, 190, 30, 15, M_PI_2, 1.5 * M_PI, 1);
    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillPath(context);
    CGContextStrokePath(context);
    
    CGContextAddArc(context, 190, 22.5, 7.5, M_PI_2, 1.5 * M_PI, 0);
    CGContextFillPath(context);
    CGContextStrokePath(context);
    
    CGContextAddArc(context, 190, 37.5, 7.5, M_PI_2, 1.5 * M_PI, 1);
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillPath(context);
    CGContextStrokePath(context);
    
    CGContextAddArc(context, 190, 22.5, 3.75, M_PI_2, 2.5 * M_PI, 0);
    CGContextFillPath(context);
    CGContextStrokePath(context);
    
    CGContextAddArc(context, 190, 37.5, 3.75, M_PI_2, 2.5 * M_PI, 0);
    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillPath(context);
    CGContextStrokePath(context);
直線
CGPoint linePoint[2] = {CGPointMake(100, 70),CGPointMake(150, 70)};
    CGContextAddLines(context, linePoint, sizeof(linePoint)/sizeof(CGPoint));//添加線
    CGContextDrawPath(context, kCGPathStroke);
笑臉
    CGContextMoveToPoint(context, 185, 60);//起始坐標
    CGContextAddArcToPoint(context, 200, 40, 210, 60, 14);//x1,y1與起始坐標形成一條直線,x1,y1與x2,y2又形成一條直線,這兩條直線確定弧線的形狀,radius是半徑
    CGContextStrokePath(context);//繪制路徑
    
    CGContextMoveToPoint(context, 225, 60);//起始坐標
    CGContextAddArcToPoint(context, 240, 40, 250, 60, 14);//
    CGContextStrokePath(context);//繪制路徑
    
    CGContextMoveToPoint(context, 197.5, 75);//起始坐標
    CGContextAddArcToPoint(context, 222, 95, 237.5, 75, 25);//
    CGContextStrokePath(context);//繪制路徑
矩形
    CGContextSetFillColorWithColor(context, [UIColor cyanColor].CGColor);//設置填充顏色
    CGContextAddRect(context, CGRectMake(60, 95, 50, 25));//畫方框
    CGContextDrawPath(context, kCGPathFillStroke);//繪制路徑
    
    //填充1:
    CAGradientLayer * gradientRectangle = [CAGradientLayer layer];
    gradientRectangle.frame = CGRectMake(130, 95, 50, 25);
    gradientRectangle.colors = @[(id)[UIColor redColor].CGColor,(id)[UIColor orangeColor].CGColor,(id)[UIColor yellowColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor cyanColor].CGColor,(id)[UIColor blueColor].CGColor,(id)[UIColor purpleColor].CGColor];
    [self.layer insertSublayer:gradientRectangle atIndex:0];
    
    //填充2:
    //創(chuàng)建填充顏色
    CGColorSpaceRef rgbColor = CGColorSpaceCreateDeviceRGB();
    CGFloat colors[] ={1,1,1, 1.00,
                       1,1,0, 1.00,
                       1,0,0, 1.00,
                       1,0,1, 1.00,
                       0,1,1, 1.00,
                       0,1,0, 1.00,
                       0,0,1, 1.00,
                       0,0,0, 1.00,};
    CGGradientRef gradient = CGGradientCreateWithColorComponents(rgbColor, colors, NULL,sizeof(colors)/(sizeof(colors[0])*4));
    CGColorSpaceRelease(rgbColor);
    
    CGContextSaveGState(context);//記錄當前的狀態(tài)
    CGContextMoveToPoint(context, 200, 95);//起始點
    CGContextAddLineToPoint(context, 220, 95);//與起始點形成一條線
    CGContextAddLineToPoint(context, 220, 120);//與上一個點形成一條線
    CGContextAddLineToPoint(context, 200, 120);//與上一個點形成一條線
    CGContextClip(context);//裁剪路徑
    
    CGContextDrawLinearGradient(context, gradient, CGPointMake(200, 95), CGPointMake(220, 120), kCGGradientDrawsAfterEndLocation);//gradient漸變顏色,startPoint開始漸變的起始位置,endPoint結束坐標,options開始坐標之前or開始之后開始漸變
    CGContextRestoreGState(context);//恢復到之前的context
   
    //矩形填充
    CGContextSaveGState(context);
    CGContextMoveToPoint(context, 240, 95);
    CGContextAddLineToPoint(context, 270, 95);
    CGContextAddLineToPoint(context, 270, 120);
    CGContextAddLineToPoint(context, 240, 120);
    CGContextClip(context);
    
    CGContextDrawLinearGradient(context, gradient, CGPointMake(240, 95), CGPointMake(240, 120), kCGGradientDrawsAfterEndLocation);
    CGContextRestoreGState(context);
    
    //圓
    CGContextDrawRadialGradient(context, gradient, CGPointMake(240, 30), 0, CGPointMake(240, 30), 15, kCGGradientDrawsBeforeStartLocation);
扇形
CGContextSetFillColorWithColor(context, [UIColor cyanColor].CGColor);
    
    //以30為半徑圍繞圓心畫指定角度扇形
    CGContextMoveToPoint(context, 130, 170);
    CGContextAddArc(context, 130, 170, 30, -0.8*M_PI_4, -3.2*M_PI_4, 1);
    CGContextClosePath(context);//關閉路徑
    CGContextDrawPath(context, kCGPathFillStroke);
橢圓
    CGContextAddEllipseInRect(context, CGRectMake(180, 145, 40, 20));
    CGContextDrawPath(context, kCGPathFillStroke);
六芒星
    CGPoint trianglePoint1[] = {CGPointMake(220, 220),CGPointMake(310, 220),CGPointMake(265, 220 - 45 * sqrtf(3.0))};
    CGContextAddLines(context, trianglePoint1, sizeof(trianglePoint1)/sizeof(CGPoint));
    CGContextClosePath(context);//關閉路徑
    CGContextDrawPath(context, kCGPathStroke);

    CGPoint trianglePoint2[] = {CGPointMake(220, 220 - 30 * sqrtf(3.0)),CGPointMake(310, 220 - 30 * sqrtf(3.0)),CGPointMake(265, 220 + 15 * sqrtf(3.0))};
    CGContextAddLines(context, trianglePoint2, sizeof(trianglePoint2)/sizeof(CGPoint));
    CGContextClosePath(context);//關閉路徑
    CGContextDrawPath(context, kCGPathStroke);
圓角矩形
    CGFloat width = 160;
    CGFloat height = 260;
    
    CGContextMoveToPoint(context, width, height - 20);//從坐標右邊開始
    CGContextAddArcToPoint(context, width, height, width - 20, height, 10);//右下角角度
    CGContextAddArcToPoint(context, 100, height, 100, height - 20, 10);//左下角度數(shù)
    CGContextAddArcToPoint(context, 100, 230, width - 20, 230, 10);//左上角
    CGContextAddArcToPoint(context, width, 230, width, height - 20, 10);//右上角
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke);
曲線
//二次曲線
    CGContextMoveToPoint(context, 120, 300);
    CGContextAddQuadCurveToPoint(context, 160, 300 - 40 * sqrtf(3.0), 200, 300);//控制點坐標和終點坐標
    CGContextAddQuadCurveToPoint(context, 240, 300 + 40 * sqrtf(3.0), 280, 300);
    CGContextStrokePath(context);
    
    //三次曲線
    CGContextSetRGBStrokeColor(context, 0, 1, 0, 1);
    CGContextMoveToPoint(context, 120, 300);
    CGContextAddCurveToPoint(context, 160, 300 - 40 * sqrtf(3.0), 240, 300 + 40 *sqrtf(3.0), 280, 300);
    CGContextStrokePath(context);

然后搞個畫板大家可以自己畫著玩

畫板

畫板分為三步:
1.開始畫曲線

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    _path = [UIBezierPath bezierPath];
    
    UITouch * myTouch = [touches anyObject];
    CGPoint point = [myTouch locationInView:self];
    
    [_path moveToPoint:point];
    
    NSDictionary * tempDict = @{@"color":[UIColor blueColor],
                                @"line":_path};
    
    [_lineArr addObject:tempDict];
    
    _undoBtn.enabled = YES;
}

2.畫完一筆

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch * myTouch = [touches anyObject];
    CGPoint point = [myTouch locationInView:self];
    
    [_path addLineToPoint:point];
    
    [self setNeedsDisplay];
}

3.顯示出來

- (void)drawRect:(CGRect)rect
{
    for (int i = 0 ; i < _lineArr.count; i++) {
        NSDictionary * tempDict = _lineArr[i];
        
        UIColor * color = tempDict[@"color"];
        UIBezierPath * line = tempDict[@"line"];
        
        [color setStroke];
        [line setLineWidth:2.0];
        [line stroke];
    }
}

我還增加了撤消和取消撤消功能:

  • 撤消
NSInteger index = self.lineArr.count - 1;

    [self.cancelArr addObject:self.lineArr[index]];

    [self.lineArr removeObjectAtIndex:index];

    [self setNeedsDisplay];
    
    _undoBtn.enabled = self.lineArr.count > 0 ? YES : NO;
    
    _cancelBtn.enabled = self.cancelArr.count > 0 ? YES : NO;

    return index;
  • 取消撤消
    NSInteger index = self.cancelArr.count - 1;

    [self.lineArr addObject:self.cancelArr[index]];

    [self.cancelArr removeObjectAtIndex:index];

    [self setNeedsDisplay];
    
    _undoBtn.enabled = self.lineArr.count > 0 ? YES : NO;
    
    _cancelBtn.enabled = self.cancelArr.count > 0 ? YES : NO;
    
    return index;

大家還可以修改顏色和線條粗細,并且還可以根據(jù)我所寫的《讓所有的開發(fā)者都能使用3D Touch》中的測算點擊力度功能來實現(xiàn)線條的粗細,我在這里就不寫了。關于文中的內(nèi)容,具體的可以參見Demo來理解,因為比較簡單,我就不分文件,寫到一個文件里了,歡迎大家Star.

版權聲明:本文為 Crazy Steven 原創(chuàng)出品,歡迎轉載,轉載時請注明出處!

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,844評論 2 372

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