iOS之简笔画

最近是有些懒了,本计划一周一篇文章的,现在都变成两周一篇了,需要反省一下。。。

写这篇文章是因为有一次看到说现在的程序员,连基本的绘图都不会,所以就和大家一起学学基本绘图吧。今天说的是绘制一些基本图形,就一些圆啊,三角啊什么的,都比较简单。

    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:
    //创建填充颜色
    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);//记录当前的状态
    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);//左下角度数
    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;

大家还可以修改颜色和线条粗细,并且还可以根据我所写的《让所有的开发者都能使用3D Touch》中的测算点击力度功能来实现线条的粗细,我在这里就不写了。关于文中的内容,具体的可以参见Demo来理解,因为比较简单,我就不分文件,写到一个文件里了,欢迎大家Star.

版权声明:本文为 Crazy Steven 原创出品,欢迎转载,转载时请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容