iOS开发UI篇——Quartz2D简介
一、Quartz2D介绍
1、什么是Quartz2D?
他是一个二维的绘图引擎,同时支持iOS和Mac系统 能够画基本线条,绘制文字,图片,截图,自定义UIView. 当我们的控件样式极其复杂时,可以把控件内部的结构给画出画,就是自定义控件.
2.什么是图形上下文(core Graphics Context)?
图形上下文是用来保存用户绘制的内容状态,并决定绘制到哪个地方的. 用户把绘制好的内容先保存到图形上下文, 然后根据选择的图形上下文的不同,绘制的内容显示到地方也不相同,即输出目标也不相同. 图形上下文的类型有: Bitmap Graphics Context(位图上下文) PDF Graphics Context Window Graphics Context Layer Graphics Context(图层上下文,自定义UIView取得上下文就是图层上下文. UIView之所以能够显示就是因为他内部有一个图层) Printer Graphics Context
3.什么时候调用drawRect?
1、重写drawRect,不用调用父类方法。 2、调用[self setNeedsDisplay];方法后会重新调用drawRect方法 ,重新绘制图形。
4. 关键代码
获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext();
贝塞尔曲线 UIBezierPath *path = [UIBezierPath bezierPath]; (其中[UIBezierPath bezierPath]是获取路径的一种方法);
设置的路径添加的上下文 CGContextAddPath(ctx, path.CGPath);
上下文渲染到view视图上 CGContextStrokePath(ctx);
设置线宽 CGContextSetLineWidth(ctx, 1);
设置线的起点 [path moveToPoint:x,y值];
添加线 [path addLineToPoint:x,y值];
画圆角矩形 [UIBezierPath bezierPathWithRoundedRect:x,y,width,height cornerRadius:圆角半径];
5.基本操作(画直线、曲线、矩形、圆、进度条)
5.1 画直线
核心思路: 起点,终点。起点是线的初始位置,终点是x,y.就是距离x轴,y轴的偏移位置,再添加线时也是按照偏移位置来定,最终距离x,y轴的偏移量,详见图1 //1上下文,获取当前上下文,Graphics图形化 CGContextRef ctx = UIGraphicsGetCurrentContext(); //2.绘制贝塞尔曲线路径 UIBezierPath *path = [UIBezierPath bezierPath]; //设置起点 [path moveToPoint:CGPointMake(200,30)]; //添加一根线到终点,距离x轴200,y轴40(相当于终点200-200,40-10,在x轴200的位置,向下移10+20个点) [path addLineToPoint:CGPointMake(200, 80)]; //画第二条线,距离x轴250,y轴200(在上一个线200的基础上向右偏移50,在上一个y轴40的基础上向下偏移160) //addLineToPoint:把上一条线的终点当作是下一条线的起点 [path addLineToPoint:CGPointMake(250, 200)]; //上下文的状态 //设置线的宽度 CGContextSetLineWidth(ctx, 1); //下面的样式没有发现有什么不一样的,然并卵, //设置线的连接样式 CGContextSetLineJoin(ctx, kCGLineJoinRound); //设置线的顶角样式 CGContextSetLineCap(ctx, kCGLineCapRound); //设置颜色 [[UIColor redColor] set]; //3.把绘制的内容添加到上下文当中. CGContextAddPath(ctx, path.CGPath); //4.把上下文的内容显示到View上(渲染到View的layer)(stroke fill) CGContextStrokePath(ctx);
图1 效果图及图解
5.2 画曲线
CGContextRef ref = UIGraphicsGetCurrentContext(); UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(50, 50)]; //controlPoint:CGPointMake(233, 30) 曲线的点 [path addQuadCurveToPoint:CGPointMake(20, 150) controlPoint:CGPointMake(233, 30)]; CGContextAddPath(ref, path.CGPath); CGContextStrokePath(ref);
5.3 画矩形、图、椭圆
圆角矩形
CGContextRef ref = UIGraphicsGetCurrentContext(); UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 100, 100) cornerRadius:50]; [[UIColor cyanColor]set]; CGContextAddPath(ref, path.CGPath); //完成路径的绘制,stroke储存 CGContextStrokePath(ref);
画椭圆或圆
CGContextRef ref = UIGraphicsGetCurrentContext(); UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 50, 250, 200)]; CGContextAddPath(ref, path.CGPath); CGContextStrokePath(ref);
画圆孤
//Center:弧所在的圆心 //radius:圆的半径 //startAngle:开始角度 //endAngle:截至角度 //clockwise: YES:顺时针 NO:逆时针 CGPoint center = CGPointMake(rect.size.width*0.5, rect.size.height*0.5); CGFloat radius = rect.size.width*0.5 - 10; //M_PI 代表PI,M_PI_2 代表 PI/2,M_PI_4 代表PI/4,-M_PI_2 相反 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:-M_PI_2 clockwise:NO]; //添加一根线到圆心 [path addLineToPoint:center]; //设置颜色 [[UIColor redColor] set]; //画扇形,填充路径 [path fill];
5.4 进度条思路及代码分析
业务逻辑:拖动滑竿的时候让他里面的能够跟着我的拖动,数字在改变. 拖动的同时,具有下载进度的效果 思路:拖动滑竿的时候就是在上面画弧. 从最上面,按顺时针画,所以,它的起始角度是-90度.结束角度也是-90度 也是从起始角度开始画, 起始角度-90度, 看你下载进度是多少 假如说你下载进度是100,就是1 * 360度 也就是说这个进度占你360度多少分之一
详见图2
//1.添加silder及绘图的视图 //1.添加silder UISlider *slidder = [[UISlider alloc] initWithFrame:CGRectMake(20, 20, 200, 40)]; [slidder addTarget:self action:@selector(slidderChange:) forControlEvents:UIControlEventValueChanged]; [self.view addSubview:slidder]; //2.添加显示图视图 DrawView *drawView = [[DrawView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(slidder.frame),self.view.bounds.size.width, 400)]; [drawView setBackgroundColor:[UIColor yellowColor]]; self.valueLabel = [[UILabel alloc] initWithFrame:drawView.bounds]; [self.valueLabel setTextAlignment:NSTextAlignmentCenter]; [drawView addSubview:self.valueLabel]; [self.view addSubview:drawView]; self.drawView = drawView; //2.当slider发生变化时, - (void)slidderChange:(UISlider *)sender{ self.valueLabel.text = [NSString stringWithFormat:@"%.2f%%",sender.value*100]; self.drawView.progressValue = sender.value; } //3.更新绘制图形 - (void)progressView:(CGRect)rect{ CGContextRef ref = UIGraphicsGetCurrentContext(); CGPoint center = CGPointMake(rect.size.width*0.5, rect.size.height*0.5); CGFloat radius = rect.size.width*0.5 -40; CGFloat startAngle = M_PI_2; CGFloat Angle = self.progressValue*M_PI *2; CGFloat endAngle = startAngle+Angle; NSLog(@"%f,%f",startAngle,endAngle); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:NO]; CGContextAddPath(ref, path.CGPath); CGContextStrokePath(ref); }
图2,效果图及图解
将来的自己,会感谢现在不放弃的自己!