拥抱Core Graphics吧!
Core Graphics用于处理本地2D向量渲染和图片渲染。其中满是名称相近,让人郁闷的C接口。
对于在iOS上编程有一段时间的人来说有别的方法也会尽量避免使用这些C函数。
毕竟直接用xCode已有控件的话,只要拖一拖,然后少许的代码就可以做出某些效果,何必
自找苦吃?!但是Core Graphics有一个很大的优点:快! ps,我不是说要重复找轮子。
绘制在drawRect:方法中进行
当一个View需要绘制的时候,drawRect:方法会被调用。在这个方法中Core Graphics就会发挥作用,
你指定的区域会被重新绘制。但是你没法直接绘制UIView,而是继承UIView并自己实现drawRect:这个方法来进行绘制。
找到绘制的上下文
在绘制先需要保证绘制所在的上下文是在当前的View中。当前上下文使用UIGraphicsGetCurrentContext获得。
对于当前上下文,可以理解为Core Graphics对于当前所操作View的绘制操作一个指针,跟踪了全部的绘制操作。在C库中很多。
相当于面向对象编程语言中一个类的self指针。示例:
2 CGContextRef ctx = UIGraphicsGetCurrentContext();
3 // 绘制操作
4 }
在之后的代码里就可以用ctx来表示当前上下文。
绘制
绘制UIImage可以非常的简单,如:
2 CGContextRef ctx = UIGraphicsGetCurrentContext();
3 UIImage *img = [UIImage imageNamed:@"MyImage.png"];
4 [img drawInRect:rect];
5 }
画线
用Core Graphics画线和平时用笔画线的逻辑是一样的。先找到起始点,放下画笔,然后给画笔一系列的指令告诉它之后
往哪里画。每往下画一段都以上一段的终点为起点。用函数CGContextMoveToPoint把画笔移动到起始点。然后用函数
CGContextAddLineToPoint指定线条的终点,并在这两点之间画线。其他,还可以指定线条的颜色等。下面用具体的代码
来说明。代码:
2 {
3 // 获取当前绘图上下文
4 CGContextRef con = UIGraphicsGetCurrentContext();
5
6 // 绘制箭杆部分
7 CGContextMoveToPoint(con, 100, 100);
8 CGContextAddLineToPoint(con, 100, 25);
9 CGContextSetLineWidth(con, 20);
10 CGContextStrokePath(con);
11
12 // 绘制箭头部分
13 CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]);
14 CGContextMoveToPoint(con, 80, 25);
15 CGContextAddLineToPoint(con, 100, 0);
16 CGContextAddLineToPoint(con, 120, 25);
17 CGContextFillPath(con);
18 }
最后结果,如图:
绘制长方形
绘制是用CGRect变量指定位置和长,宽值。然后把该变量作为参数传给函数CGContextAddRect
2
3 CGContextRef context = UIGraphicsGetCurrentContext();
4
5 CGContextSetLineWidth(context, 2.0);
6
7 CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
8
9 CGRect rectangle = CGRectMake(60,170,200,80);
10
11 CGContextAddRect(context, rectangle);
12
13 CGContextStrokePath(context);
14 }
效果如下:
绘制上下文状态保存
从上面绘制的例子中可以看出。即使只是简单的画一条线也需要调好几个函数来设置这条线的
颜色、宽度,沿着哪条路径绘制等属性。 Core Graphics会保存这些属性在其内部的栈中。这个绘制状态就好比是一直笔,
你可以换笔头,颜色来画出不同的效果。但是如果你忘记把所有的东西换回去,那么下次再画出来的效果难保不会出乎意料。
函数CGContextSaveGState和函数CGContextRestoreGState专门用来处理绘制状态。CGContextSaveGState函数
就相当于给你当前的绘制状态打了个书签,之后你可以任意修改你想要修改的属性。然后可以用函数CGContextRestoreGState来重置绘制状态,
回到打了书签的地方。这两个函数必须要配对使用! 否则的话,绘制状态就全部乱了,要不绘出来的不是你想要,要不绘制都无法继续。
2 {
3 CGContextRef ctx = UIGraphicsGetCurrentContext();
4
5 // 设置属性
6 CGColorRef whiteColor = [UIColor whiteColor].CGColor;
7 CGColorRef lightColor = _lightColor.CGColor;
8 CGColorRef darkColor = _darkColor.CGColor;
9 CGColorRef shadowColor = [UIColor colorWithRed:.2f green:.2f blue:.2f alpha:.5f].CGColor;
10
11 CGContextSetFillColorWithColor(ctx, whiteColor);
12 CGContextFillRect(ctx, _paperRect);
13
14 // 保存绘制属性
15 CGContextSaveGState(ctx);
16
17 // 绘制。。。
18
19 // 还原绘制属性
20 CGContextRestoreGState(ctx);
21 }
View的重绘
苹果文档的一段话说的非常清楚:
任何时候,当视图的一部分需要重画时,UIView
对象内置的描画代码就会调用其drawRect:
方法,并向它传入一个包含需要重画的视图区域的矩形。您需要在定制视图子类中重载这个方法,并在这个方法中描画视图的内容。在首次描画视图时,UIView传递给drawRect:
方法的矩形包含视图的全部可见区域。但在随后的调用中,该矩形只代表实际需要被描画的部分。触发视图更新的动作有如下几种:
对遮挡您的视图的其它视图进行移动或删除操作。
将视图滚出屏幕,然后再重新回到屏幕上。
显式调用视图的
setNeedsDisplay
或者setNeedsDisplayInRect:
方法。
在调用drawRect:
方法之后,视图会将自己标志为已更新,然后等待新的更新动作触发下一个更新周期。如果您的视图显示的是静态内容,则只需要在视图的可见性发生变化时进行响应就可以了,这种变化可能由滚动或其它视图是否被显示引起的。然而,如果您需要周期性地更新视图内容,就必须确定什么时候调用setNeedsDisplay
或setNeedsDisplayInRect:
方法来触发更新。举例来说,如果您需要每秒数次地更新内容,则可能要使用一个定时器。在响应用户交互或生成新的视图内容时,也可能需要更新视图。
最后,暂时先总结这么多,后面会陆续深入讲解这部分内容。只要参考着苹果的官方文档多练。在实际开发中多用。你自然会对Core Graphics驾轻就熟。
希望此文对你有所帮助。谢谢!