引入了Core Graphices框架功能,演示如何画线条,文本,改变线条的额粗细,颜色,以及保存和恢复图形上下文。

要在一个视图中进行自定义绘制,我们必须首先获得当前图形上下文。图形上下文(CGContext)是一个绘图画布,它存放绘图信息,如颜色,线条宽度和字体。在调用drawRect:之前,由UIView配置当前图形上下文。UIGraphicsGetCurrentContext函数返回已经为当前UIView所配置的图形上下文。

 

  1. //获取当前图形上下文 
  2. CGContextRef context = UIGraphicsGetCurrentContext(); 
  3.  
  4. //保存这个上下文,因为我们需要上下翻转它 
  5. CGContextSaveGState(context);/*通过调用CGContextRef中的CGContextTranslateCTM函数把坐标原点转换到左下角,该函数有两个参数,即水平和垂直方向的变换数值。然后使用CGContextScaleCTM函数颠倒y轴,该函数有两个参数,即x轴和y轴的变换比例,第一个参数为1,保持x轴不变,而第二个参数为-1,表示颠倒y轴*/    //向下移动该上下文坐标原点 
  6. CGContextTranslateCTM(context, 0, self.view.bounds.size.height); 
  7. CGContextScaleCTM(context, 1.0, -1.0);      //向上翻转图像上下文 
  8.  
  9. //以剩余时间来创建一个字符串 
  10. NSString  *str = [NSString stringWithFormat:@"Time remaining:%i seconds", timeLeft]; 
  11.  
  12. //选择字体为16pt Helvetica 
  13. CGContextSelectFont(context, "Helvetica", 16, kCGEncodingMacRoman); 
  14. CGContextSetTextDrawingMode(context, kCGTextFill);      //设置绘制模式 
  15.  
  16. //设置文本颜色为黑色 
  17. CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); 
  18.  
  19. //转换str为一个C 字符串并显示它 
  20. CGContextShowTextAtPoint(context, 10.0, 10.0, [str cStringUsingEncoding:[NSString defaultCStringEncoding]], str.length); 
  21. CGContextRestoreGState(context);    //恢复上下文 
  22.  
  23. //如果炮弹在屏幕上 
  24. if (cannonballOnScreen)  
  25.     //创建矩形并在其中绘制炮弹 
  26.     CGRect cannonballRect = CGRectMake(cannonball.x, cannonball.y, CANNON_BASE_RADIUS * 2, CANNON_BASE_RADIUS * 2); 
  27.     UIImage *p_w_picpath = [UIImage p_w_picpathNamed:@"cannonball80.png"]; 
  28.      
  29.     //绘制图片到矩形中 
  30.     CGContextDrawImage(context, cannonballRect, p_w_picpath.CGImage); 
  31.  
  32. //绘制加农炮炮管 
  33. //移动加农炮底座到视图中间的位置 
  34. CGContextMoveToPoint(context, 0 , self.view.frame.size.height / 2); 
  35.  
  36. //添加一根到加农炮炮管终端的线条 
  37. CGContextAddLineToPoint(context, barrelEnd.x , barrelEnd.y); 
  38. CGContextSetLineWidth(context, 20);             //设置线条粗细 
  39. CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);        //黑色 
  40. CGContextStrokePath(context);       //绘制线条 
  41.  
  42. //为加农炮底座创建矩形 
  43. CGRect cannonBase = CGRectMake(0, self.view.frame.size.height / 2 - CANNON_BASE_RADIUS, CANNON_BASE_RADIUS, CANNON_BASE_RADIUS * 2); 
  44.  
  45. //加载加农炮底座图片 
  46. UIImage *baseImage = [UIImage p_w_picpathNamed:@"cannon_base.png"]; 
  47.  
  48. //把加农炮底座图片绘制到矩形中 
  49. CGContextDrawImage(context, cannonBase, baseImage.CGImage); 
  50.  
  51. //在拦截器两个端点之间添加一根线 
  52. CGContextMoveToPoint(context, blocker.start.x, blocker.start.y); 
  53. CGContextAddLineToPoint(context, blocker.end.x, blocker.end.y); 
  54. CGContextSetLineWidth(context, LINE_WIDTH); 
  55.  
  56. CGContextStrokePath(context);       //绘制线条 
  57.  
  58. //计算目标每个分段的长度 
  59. float pieceLength = (TARGET_END - TARGET_BEGINING) / TARGET_PIECES; 
  60.  
  61. //移到目标起点 
  62. CGContextMoveToPoint(context, target.start.x, target.start.y); 
  63.  
  64. //绘制每个目标分段 
  65. for (int i = 1; i <= TARGET_PIECES; i++) 
  66.     //相邻分段以黄、蓝色区分开 
  67.     if(i % 2 == 0) 
  68.     { 
  69.         CGContextSetRGBStrokeColor(context, 1, 1, 0, 1); 
  70.     } 
  71.     else  
  72.     { 
  73.         CGContextSetRGBStrokeColor(context, 0, 0, 0.5, 1); 
  74.     } 
  75.      
  76.     //移到下一个分段的端点 
  77.     CGContextMoveToPoint(context, target.end.x, target.start.y + pieceLength * (i - 1)); 
  78.      
  79.     //如果这个分段还没有被击中 
  80.     if(!targetPieceHit[i - 1]) 
  81.     { 
  82.         //为该分段添加一条线 
  83.         CGContextAddLineToPoint(context, target.end.x, target.start.y + pieceLength * i); 
  84.         CGContextStrokePath(context);      //绘制分段 
  85.     } 
  86.     }