Quartz 2D

1.什麼是Quart 2D呢?數組

不知道,可是能夠經過Quart2D繪製圖形,自定義控件等等.app

2.如何經過Quart 2D繪製圖形和自定義控件?函數

有兩種方式:C語言/OC;OC其實最後仍是轉換成C,那麼用C會不會效率稍高?spa

3.基本圖形的繪製code

  • C語言方式
    • 獲取當前圖形上下文 :
          CGContextRef ctx = UIGraphicsGetCurrentContext();
    • 繪製圖形:
      圓:CGContextRef _Nullable c:圖形上下文; CGFloat x, CGFloat y:圓心座標;CGFloat radius:半徑;CGFloat startAngle:開始角度;CGFloat endAngle:結束角度;int clockwise:繪製的方向(順時針仍是逆時針)
      [CGContextAddArc(CGContextRef _Nullable c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise) ];
      橢圓:CGRect rect:一個矩形範圍.
      [CGContextAddEllipseInRect(CGContextRef _Nullable c, CGRect rect) ];
      線:(給定一些點,鏈接成線) const CGPoint * _Nullable points:CGPoint類型的數組;size_t count:有幾個點
      [CGContextAddLines(CGContextRef _Nullable c,
      const CGPoint * _Nullable points, size_t count) ];
      矩形:
      [CGContextAddRect(CGContextRef _Nullable c, CGRect rect) ];

      線:
      [CGContextMoveToPoint(CGContextRef  _Nullable c, CGFloat x, CGFloat y) ];
      [CGContextAddLineToPoint(CGContextRef  _Nullable c, CGFloat x, CGFloat y) ];
    • 渲染:填充/描邊
    •   [CGContextStrokePath(CGContextRef  _Nullable c) ];//描邊
      [CGContextFillPath(CGContextRef _Nullable c) ];//填充
  • OC方式
    • 繪製
    • 圓:  
      [UIBezierPath bezierPathWithArcCenter:(CGPoint) radius:(CGFloat) startAngle:(CGFloat) endAngle:(CGFloat) clockwise:(BOOL)];
      矩形:
      [UIBezierPath bezierPathWithRect:(CGRect)];

      圓角矩形:cornerRadius:(CGFloat):圓角實際上經過在矩形邊角處繪製圓,而後將弧線外面部分截取掉實現的.此參數表明圓的半徑,值越大,邊角越圓 [UIBezierPath bezierPathWithRoundedRect:(CGRect) cornerRadius:(CGFloat)];

      線:
        UIBezierPath *path = [UIBezierPath bezierPath];//首先要獲取UIBezierPath對象,調用對象方法畫線
         [path moveToPoint:(CGPoint)];
         [path addLineToPoint:(CGPoint)];
    • 渲染
    •    UIBezierPath *path = [UIBezierPath bezierPath];
         [path fill];
         [path stroke];

 4.奇偶性原則對象

   有圖形A,圖形B,圖形A,B有部份內容重合,設置使用奇偶性原則,設置填充模式,則重合次數爲奇數次填充,偶數次不填充.blog

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddArc(ctx, 100, 100, 100, 0, M_PI * 2, 0);
    CGContextAddArc(ctx, 200, 100, 100, 0, M_PI * 2, 0);
    CGContextDrawPath(ctx, kCGPathEOFill);

增長一行代碼,再多畫一個圓:ip

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddArc(ctx, 100, 100, 100, 0, M_PI * 2, 0);
    CGContextAddArc(ctx, 200, 100, 100, 0, M_PI * 2, 0);
    CGContextAddArc(ctx, 150, 200, 100, 0, M_PI * 2, 0);
    CGContextDrawPath(ctx, kCGPathEOFill);

效果:it

多出來的三角形:實際上多出來的三角形恰好是三個圓的起點.此種方式默認將圖形的路徑鏈接起來了.三角形部分一樣遵照奇偶性原則.table

OC實現一樣的效果:

   UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path addArcWithCenter:CGPointMake(200, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path addArcWithCenter:CGPointMake(150, 200) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    path.usesEvenOddFillRule = YES;

    [path fill];

那麼如何才能設置奇偶性,同時又不讓各個圖形的路徑鏈接起來呢?

OC實現:

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path appendPath:path2];
    UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 200) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path appendPath:path3];
    path.usesEvenOddFillRule = YES;
    [path fill];

C實現方式:

    CGContextRef ctx = UIGraphicsGetCurrentContext();
CGMutablePathRef path
= CGPathCreateMutable(); CGPathAddArc(path, NULL, 100, 100, 100, 0, M_PI * 2, 1);
CGMutablePathRef path2
= CGPathCreateMutable(); CGPathAddArc(path2, NULL, 200, 100, 100, 0, M_PI * 2, 1);
CGMutablePathRef path3
= CGPathCreateMutable(); CGPathAddArc(path3, NULL, 150, 200, 100, 0, M_PI * 2, 1);
CGPathAddPath(path, NULL, path2); CGPathAddPath(path, NULL, path3); CGContextAddPath(ctx, path); CGContextDrawPath(ctx, kCGPathEOFill);

除了這些應該還有不少其餘的實現方式.另外,我仍是不理解直接直接繪製的方式和經過路徑繪製的方有什麼區別.

5.非零環繞數規則.

效果:

C實現方式:

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, 200, 200, 50, 0, M_PI * 2, 1);

    CGMutablePathRef path2 = CGPathCreateMutable();
    CGPathAddArc(path2, NULL, 200, 200, 100, 0, M_PI * 2, 0);

    CGMutablePathRef path3 = CGPathCreateMutable();
    CGPathAddArc(path3, NULL, 200, 200, 200, 0, M_PI * 2, 1);

    CGPathAddPath(path, NULL, path2);
    CGPathAddPath(path, NULL, path3);

    CGContextAddPath(ctx, path);
    CGContextDrawPath(ctx, kCGPathFill);

貌似純OC代碼不能實現,由於若是最後經過函數 CGContextDrawPath(ctx, kCGPathFill);渲染,就必須獲取當前圖形上下文.而若是不一樣過該函數渲染,純OC貌似只有Fill,Stroke兩種渲染方式.

  CGContextRef ctx = UIGraphicsGetCurrentContext();

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:0];
    UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:200 startAngle:0 endAngle:M_PI * 2 clockwise:1];

    CGContextAddPath(ctx, path.CGPath);
    CGContextAddPath(ctx, path2.CGPath);
    CGContextAddPath(ctx, path3.CGPath);

    CGContextDrawPath(ctx, kCGPathFill);
相關文章
相關標籤/搜索