引入了Core Graphices框架功能,演示如何画线条,文本,改变线条的额粗细,颜色,以及保存和恢复图形上下文。
要在一个视图中进行自定义绘制,我们必须首先获得当前图形上下文。图形上下文(CGContext)是一个绘图画布,它存放绘图信息,如颜色,线条宽度和字体。在调用drawRect:之前,由UIView配置当前图形上下文。UIGraphicsGetCurrentContext函数返回已经为当前UIView所配置的图形上下文。
//获取当前图形上下文 CGContextRef context = UIGraphicsGetCurrentContext(); //保存这个上下文,因为我们需要上下翻转它 CGContextSaveGState(context);
/*通过调用CGContextRef中的CGContextTranslateCTM函数把坐标原点转换到左下角,该函数有两个参数,即水平和垂直方
向的变换数值。然后使用CGContextScaleCTM函数颠倒y轴,该函数有两个参数,即x轴和y轴的变换比例,第一个参数为1,保
持x轴不变,而第二个参数为-1,表示颠倒y轴*/
//向下移动该上下文坐标原点 CGContextTranslateCTM(context, 0, self.view.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); //向上翻转图像上下文 //以剩余时间来创建一个字符串 NSString *str = [NSString stringWithFormat:@"Time remaining:%i seconds", timeLeft]; //选择字体为16pt Helvetica CGContextSelectFont(context, "Helvetica", 16, kCGEncodingMacRoman); CGContextSetTextDrawingMode(context, kCGTextFill); //设置绘制模式 //设置文本颜色为黑色 CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); //转换str为一个C 字符串并显示它 CGContextShowTextAtPoint(context, 10.0, 10.0, [str cStringUsingEncoding:[NSString defaultCStringEncoding]], str.length); CGContextRestoreGState(context); //恢复上下文 //如果炮弹在屏幕上 if (cannonballOnScreen) { //创建矩形并在其中绘制炮弹 CGRect cannonballRect = CGRectMake(cannonball.x, cannonball.y, CANNON_BASE_RADIUS * 2, CANNON_BASE_RADIUS * 2); UIImage *image = [UIImage imageNamed:@"cannonball80.png"]; //绘制图片到矩形中 CGContextDrawImage(context, cannonballRect, image.CGImage); } //绘制加农炮炮管 //移动加农炮底座到视图中间的位置 CGContextMoveToPoint(context, 0 , self.view.frame.size.height / 2); //添加一根到加农炮炮管终端的线条 CGContextAddLineToPoint(context, barrelEnd.x , barrelEnd.y); CGContextSetLineWidth(context, 20); //设置线条粗细 CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0); //黑色 CGContextStrokePath(context); //绘制线条 //为加农炮底座创建矩形 CGRect cannonBase = CGRectMake(0, self.view.frame.size.height / 2 - CANNON_BASE_RADIUS, CANNON_BASE_RADIUS, CANNON_BASE_RADIUS * 2); //加载加农炮底座图片 UIImage *baseImage = [UIImage imageNamed:@"cannon_base.png"]; //把加农炮底座图片绘制到矩形中 CGContextDrawImage(context, cannonBase, baseImage.CGImage); //在拦截器两个端点之间添加一根线 CGContextMoveToPoint(context, blocker.start.x, blocker.start.y); CGContextAddLineToPoint(context, blocker.end.x, blocker.end.y); CGContextSetLineWidth(context, LINE_WIDTH); CGContextStrokePath(context); //绘制线条 //计算目标每个分段的长度 float pieceLength = (TARGET_END - TARGET_BEGINING) / TARGET_PIECES; //移到目标起点 CGContextMoveToPoint(context, target.start.x, target.start.y); //绘制每个目标分段 for (int i = 1; i <= TARGET_PIECES; i++) { //相邻分段以黄、蓝色区分开 if(i % 2 == 0) { CGContextSetRGBStrokeColor(context, 1, 1, 0, 1); } else { CGContextSetRGBStrokeColor(context, 0, 0, 0.5, 1); } //移到下一个分段的端点 CGContextMoveToPoint(context, target.end.x, target.start.y + pieceLength * (i - 1)); //如果这个分段还没有被击中 if(!targetPieceHit[i - 1]) { //为该分段添加一条线 CGContextAddLineToPoint(context, target.end.x, target.start.y + pieceLength * i); CGContextStrokePath(context); //绘制分段 } }