1.什麼是Quart 2D呢?數組
不知道,可是能夠經過Quart2D繪製圖形,自定義控件等等.app
2.如何經過Quart 2D繪製圖形和自定義控件?函數
有兩種方式:C語言/OC;OC其實最後仍是轉換成C,那麼用C會不會效率稍高?spa
3.基本圖形的繪製code
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) ];//填充
圓:
[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);