1. 程式人生 > >drawRect的繪製的使用(繪製文字字元、繪製圖片、繪製圖形)

drawRect的繪製的使用(繪製文字字元、繪製圖片、繪製圖形)

通過重寫UIView的drawRect方法進行繪製使用,如繪製文字字元、繪製圖片、繪製圖形等。

在iOS中使用drawRect繪圖一般分為以下5個步驟:
1、獲取繪圖上下文
CGContextRef context = UIGraphicsGetCurrentContext();
2、建立並設定路徑
3、將路徑新增到上下文
如:線寬、線條顏色、填充顏色等
4、設定上下文狀態
CGContextAddLines(context, points, 2);
或線
CGContextAddLineToPoint(context, 10.0, 10.0);
或圓
CGContextAddEllipseInRect(context, CGRectZero);
CGContextAddArc(context, 10.0, 10.0, (60.0 * M_PI / 180.0), (120.0 * M_PI / 180.0), 1); 
或弧
CGContextAddArcToPoint(context, 10.0, 200.0, 300.0, 200.0, 100.0);
或二次曲線
CGContextAddQuadCurveToPoint(context, 50.0, 80.0, 200.0, 10.0);
或三次曲線 
CGContextAddCurveToPoint(context, 250, 280, 250, 400, 280.0, 300.0);
5、繪製路徑
CGContextDrawPath(context, kCGPathFillStroke);

CGContextStrokePath(context);
6、釋放路徑
CGPathRelease(path);

注意事項:

1、設定frame的屬性,或呼叫setNeedsDisplay時才會呼叫drawRect方法。

2、在繪製過程中

(1)針對實際情況獲取圖形上下文

CGContextRef context = UIGraphicsGetCurrentContext();

(2)有時候,還需要在獲取圖形上下文之前,設定開始圖形上下文;在使用後,設定關閉圖形上下文

UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0); // 開始圖形上下文

CGContextRef context = UIGraphicsGetCurrentContext();
// coding...

UIGraphicsEndImageContext(); // 關閉上下文

3、

1、繪製文字

- (void)drawRect:(CGRect)rect
{
    NSString *text = @"devZhang is an iOS developer.iOS開發者 iOS開發者 iOS開發者 iOS開發者 iOS開發者";
    // 文字段落樣式
    NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle alloc] init];
    textStyle.lineBreakMode = NSLineBreakByWordWrapping; // 結尾部分的內容以……方式省略 ( "...wxyz" ,"abcd..." ,"ab...yz")
    textStyle.alignment = NSTextAlignmentLeft; //(兩端對齊的)文字對齊方式:(左,中,右,兩端對齊,自然)
    textStyle.lineSpacing = 5; // 字型的行間距
    textStyle.firstLineHeadIndent = 5.0; // 首行縮排
    textStyle.headIndent = 0.0; // 整體縮排(首行除外)
    textStyle.tailIndent = 0.0; //
    textStyle.minimumLineHeight = 20.0; // 最低行高
    textStyle.maximumLineHeight = 20.0; // 最大行高
    textStyle.paragraphSpacing = 15; // 段與段之間的間距
    textStyle.paragraphSpacingBefore = 22.0f; // 段首行空白空間/* Distance between the bottom of the previous paragraph (or the end of its paragraphSpacing, if any) and the top of this paragraph. */
    textStyle.baseWritingDirection = NSWritingDirectionLeftToRight; // 從左到右的書寫方向(一共➡️三種)
    textStyle.lineHeightMultiple = 15; /* Natural line height is multiplied by this factor (if positive) before being constrained by minimum and maximum line height. */
    textStyle.hyphenationFactor = 1; //連字屬性 在iOS,唯一支援的值分別為0和1
    // 文字屬性
    NSMutableDictionary *textAttributes = [[NSMutableDictionary alloc] init];
    // NSParagraphStyleAttributeName 段落樣式
    [textAttributes setValue:textStyle forKey:NSParagraphStyleAttributeName];
    // NSFontAttributeName 字型名稱和大小
    [textAttributes setValue:[UIFont systemFontOfSize:12.0] forKey:NSFontAttributeName];
    // NSForegroundColorAttributeNam 顏色
    [textAttributes setValue:[UIColor redColor] forKey:NSForegroundColorAttributeName];
    // 繪製文字
    [text drawInRect:rect withAttributes:textAttributes];
}


2、繪製圖片

// 繪製圖片
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    // 儲存初始狀態
    CGContextSaveGState(context);
    // 圖形上下文移動{x,y}
    CGContextTranslateCTM(context, 50.0, 30.0);
    // 圖形上下文縮放{x,y}
    CGContextScaleCTM(context, 0.8, 0.8);
    // 旋轉
    CGContextRotateCTM(context, M_PI_4 / 4); 
    
    // 繪製圖片
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"girl" ofType:@"jpg"];
    UIImage *image = [[UIImage alloc] initWithContentsOfFile:imagePath];
    
    CGRect rectImage = CGRectMake(0.0, 0.0, rect.size.width, (rect.size.width * image.size.height / image.size.width));
    
    // 圓角圖片設定
//    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0); // 開始圖形上下文
//    CGContextRef ctx = UIGraphicsGetCurrentContext(); // 獲得圖形上下文
//    CGRect rectNew = CGRectMake(0, 0, rect.size.width, rect.size.height); // 設定一個範圍
//    CGContextAddEllipseInRect(ctx, rect); // 根據一個rect建立一個橢圓
//    CGContextClip(ctx); // 裁剪
//    [image drawInRect:rectNew]; // 將原照片畫到圖形上下文
//    image = UIGraphicsGetImageFromCurrentImageContext(); // 從上下文上獲取剪裁後的照片
//    UIGraphicsEndImageContext(); // 關閉上下文
    
    // 繪製圖片
    // 1 圖片可能顯示不完整
//    [image drawAtPoint:CGPointMake(0, 0)];
    
    // 2 在rect範圍內完整顯示圖片-正常使用
    [image drawInRect:rectImage];
    
    // 3 圖片上下顛倒了
//    CGContextRef context = UIGraphicsGetCurrentContext();
//    CGContextDrawImage(context, rectImage, image.CGImage);
    
    // 4 圖片上下顛倒了-n個顯示
//    CGContextRef context = UIGraphicsGetCurrentContext();
//    CGContextDrawTiledImage(context, rectImage, image.CGImage);
    
    // 恢復到初始狀態
    CGContextRestoreGState(context);
}



3、繪製圖形

(1)菱形、矩形、正方形

- (void)drawRect:(CGRect)rect
{
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 畫一個菱形-實線帶邊框,帶填充
    // 邊框
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor magentaColor].CGColor);
    // 方法1 菱形起點-終點
//    CGContextMoveToPoint(context, 10.0, 80.0);
//    CGContextAddLineToPoint(context, 60.0, 10.0);
//    CGContextAddLineToPoint(context, 110.0, 80.0);
//    CGContextAddLineToPoint(context, 60.0, 150.0);
//    CGContextAddLineToPoint(context, 10.0, 80.0);
    // 方法2 菱形起點-終點
    CGPoint points[5] = {CGPointMake(10.0, 80.0), CGPointMake(60.0, 10.0), CGPointMake(110.0, 80.0), CGPointMake(60.0, 150.0), CGPointMake(10.0, 80.0)};
    CGContextAddLines(context, points, 5);
    // 填充
    CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
    // 繪製路徑及填充模式
    CGContextDrawPath(context, kCGPathFillStroke);
    
    // 畫一個菱形-虛線帶邊框,無填充
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGFloat dashArray[] = {4, 4}; // 表示先畫1個點再畫4個點(前者小後者大時,虛線點小且間隔大;前者大後者小時,虛線點大且間隔小)
    CGContextSetLineDash(context, 1, dashArray, 2); // 其中的2表示dashArray中的值的個數
    // 菱形起點-終點
    CGPoint pointsStroke[5] = {CGPointMake(120.0, 80.0), CGPointMake(170.0, 10.0), CGPointMake(220.0, 80.0), CGPointMake(170.0, 150.0), CGPointMake(120.0, 80.0)};
    CGContextAddLines(context, pointsStroke, 5);
    // 方法1 繪製路徑及填充模式
//    CGContextDrawPath(context, kCGPathStroke);
    // 方法2 繪製路徑
    CGContextStrokePath(context);
    
    // 畫一個菱形-無邊框,帶填充
    CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
    // 菱形起點-終點
    CGPoint pointsFill[5] = {CGPointMake(230.0, 80.0), CGPointMake(260.0, 10.0), CGPointMake(290.0, 80.0), CGPointMake(260.0, 150.0), CGPointMake(230.0, 80.0)};
    CGContextAddLines(context, pointsFill, 5);
    // 方法1 繪製路徑及填充模式
    CGContextDrawPath(context, kCGPathFill);

    
    // 通過frame的寬高區分正方形,矩形
    // 畫一個正方形-帶邊框,帶填充
    // 邊框
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    // 正方形起點-終點
    CGPoint pointsRect[5] = {CGPointMake(10.0, 160.0), CGPointMake(60.0, 160.0), CGPointMake(60.0, 210.0), CGPointMake(10.0, 210.0), CGPointMake(10.0, 160.0)};
    CGContextAddLines(context, pointsRect, 5);
    // 填充
    CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
    // 繪製路徑及填充模式
    CGContextDrawPath(context, kCGPathFillStroke);
    
    // 畫一個正方形-帶邊框,無填充
    // 邊框
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    // 方法1 正方形起點-終點
//    CGPoint pointsRect2[5] = {CGPointMake(70.0, 160.0), CGPointMake(120.0, 160.0), CGPointMake(120.0, 210.0), CGPointMake(70.0, 210.0), CGPointMake(70.0, 160.0)};
//    CGContextAddLines(context, pointsRect2, 5);
    // 方法2
//    CGContextAddRect(context, CGRectMake(70.0, 160.0, 50.0, 50.0));
    // 方法3
    CGContextStrokeRect(context, CGRectMake(70.0, 160.0, 50.0, 50.0));
    // 方法1 繪製路徑及填充模式
//    CGContextDrawPath(context, kCGPathStroke);
    // 方法2 繪製路徑
    CGContextStrokePath(context);

    
    // 畫一個正方形-無邊框,帶填充
    CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
    // 方法1 填充
//    CGContextFillRect(context, CGRectMake(130.0, 160.0, 50.0, 50.0));
    // 方法2
    CGContextAddRect(context, CGRectMake(130.0, 160.0, 50.0, 50.0));
    CGContextDrawPath(context, kCGPathFill);


    
    
    // 畫一個矩形-帶邊框,帶填充
    // 邊框
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor brownColor].CGColor);
    // 矩形起點-終點
    CGPoint pointsRectangle[5] = {CGPointMake(10.0, 220.0), CGPointMake(80.0, 220.0), CGPointMake(80.0, 270.0), CGPointMake(10.0, 270.0), CGPointMake(10.0, 220.0)};
    CGContextAddLines(context, pointsRectangle, 5);
    // 填充
    CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);
    // 繪製路徑及填充模式
    CGContextDrawPath(context, kCGPathFillStroke);
    
    // 畫一個矩形-帶邊框,無填充
    // 邊框
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
    // 方法1 正方形起點-終點
//    CGPoint pointsRect2[5] = {CGPointMake(90.0, 220.0), CGPointMake(160.0, 220.0), CGPointMake(160.0, 270.0), CGPointMake(90.0, 270.0), CGPointMake(90.0, 220.0)};
//    CGContextAddLines(context, pointsRect2, 5);
    // 方法2
//    CGContextAddRect(context, CGRectMake(90.0, 220.0, 70.0, 50.0));
    // 方法3
    CGContextStrokeRect(context, CGRectMake(90.0, 220.0, 70.0, 50.0));
    // 方法1 繪製路徑及填充模式
//    CGContextDrawPath(context, kCGPathStroke);
    // 方法2 繪製路徑
    CGContextStrokePath(context);
    
    
    // 畫一個矩形-無邊框,帶填充
    CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);
    // 方法1 填充
//    CGContextFillRect(context, CGRectMake(170.0, 220.0, 70.0, 50.0));
    // 方法2
    CGContextAddRect(context, CGRectMake(170.0, 220.0, 70.0, 50.0));
    CGContextDrawPath(context, kCGPathFill);
}


(2)圓形、橢圓形、扇形

// 橢圓形,或圓形,扇形
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 背景顏色設定
    [[UIColor yellowColor] set];
    CGContextFillRect(context, rect);
    
    
    // 設定長寬,區分橢圓或圓
    CGRect rectRing = CGRectMake(10.0, 10.0, (rect.size.width - 10.0 * 2), 100.0);
    
    // 實線橢圓
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    CGContextAddEllipseInRect(context, rectRing);
    CGContextDrawPath(context, kCGPathStroke);
    
    // 虛線橢圓
    rectRing = CGRectMake(10.0, 120.0, (rect.size.width - 10.0 * 2), 100.0);
    CGFloat dashArray[] = {2, 6};
    CGContextSetLineDash(context, 1, dashArray, 2);
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextAddEllipseInRect(context, rectRing);
    CGContextDrawPath(context, kCGPathStroke);
    
    // 實線圓-有邊框,無填充
    rectRing = CGRectMake(10.0, 230.0, 80.0, 80.0);
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    CGContextAddEllipseInRect(context, rectRing);
    CGContextDrawPath(context, kCGPathStroke);
    
    // 實線圓-有邊框,有填充
    // 邊框
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
    // 填充
    CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);// 填充顏色
    CGContextAddArc(context, 140.0, 270.0, 40.0, 0, 2 * M_PI, 0); // 新增一個圓{x,y}中心點位置
    // kCGPathFill填充非零繞數規則,kCGPathEOFill表示用奇偶規則,kCGPathStroke路徑,kCGPathFillStroke路徑填充,kCGPathEOFillStroke描線
    CGContextDrawPath(context, kCGPathFillStroke);
    
    // 實線圓-無邊框,有填充
    rectRing = CGRectMake(190.0, 230.0, 80.0, 80.0);
    CGContextAddEllipseInRect(context, rectRing);
    [[UIColor orangeColor] set];
    CGContextFillPath(context);
    
    
    
    // 扇形
    // 實線-有邊框,有填充
    // 邊框
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
    CGContextMoveToPoint(context, 50.0, 380.0);
    // 填充
    CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);// 填充顏色
    CGContextAddArc(context, 50.0, 380.0, 60.0, (-60 * M_PI / 180), (-120 * M_PI / 180), 1); // 新增一個圓{x,y}中心點位置
    CGContextClosePath(context);
    // kCGPathFill填充非零繞數規則,kCGPathEOFill表示用奇偶規則,kCGPathStroke路徑,kCGPathFillStroke路徑填充,kCGPathEOFillStroke描線
    CGContextDrawPath(context, kCGPathFillStroke);
}




(3)實線、虛線

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 畫實線 方法1
    // 線條寬
    CGContextSetLineWidth(context, 1.0);
    // 線條顏色
    CGContextSetRGBStrokeColor(context, 1.5, 0.0, 0.0, 1.0); // 方法1
//    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); // 方法2
    // 座標點陣列
    CGPoint aPoints[2];
    aPoints[0] = CGPointMake(10.0, 20.0);
    aPoints[1] = CGPointMake((rect.size.width - 10.0), 20.0);
    // 新增線 points[]座標陣列,和count大小
    CGContextAddLines(context, aPoints, 2);
    // 根據座標繪製路徑
    CGContextDrawPath(context, kCGPathStroke);
    
    
    // 畫實線 方法2
    // 線條寬
    CGContextSetLineWidth(context, 5.0);
    // 線條顏色
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    // 起點座標
    CGContextMoveToPoint(context, 10.0, 40.0);
    // 終點座標
    CGContextAddLineToPoint(context, (rect.size.width - 10.0), 40.0);
    // 繪製路徑
    CGContextStrokePath(context);

    
    // 畫虛線
    // 線條寬
    CGContextSetLineWidth(context, 2.0);
    // 線條顏色
    CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
    // 虛線
    CGFloat dashArray[] = {1, 4}; // 表示先畫1個點再畫4個點(前者小後者大時,虛線點小且間隔大;前者大後者小時,虛線點大且間隔小)
    CGContextSetLineDash(context, 1, dashArray, 2); // 其中的2表示dashArray中的值的個數
    // 起點
    CGContextMoveToPoint(context, 10.0, 60.0);
    // 終點
    CGContextAddLineToPoint(context, (rect.size.width - 10.0), 60.0);
    // 繪製路徑
    CGContextStrokePath(context);
}


(4)曲線、弧線

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 繪製貝塞爾曲線
    // 二次曲線
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor orangeColor].CGColor);
    // 起點
    CGContextMoveToPoint(context, 10.0, 10.0);
    // 設定貝塞爾曲線的控制點座標{cp1x,cp1y} 終點座標{x,y}
    CGContextAddQuadCurveToPoint(context, (rect.size.width / 2), 80.0, (rect.size.width - 10.0), 10.0);
    // 繪製前設定顏色
    // 方法1-只有邊框顏色
//    [[UIColor blueColor] setStroke];
//    CGContextStrokePath(context);
    // 方法2-邊框和填充顏色
    [[UIColor blueColor] setStroke];
    [[UIColor yellowColor] setFill];
    CGContextDrawPath(context, kCGPathFillStroke);
    
    
    
    // 三次曲線
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
    // 起點
    CGContextMoveToPoint(context, 10.0, 200.0);
    // 設定貝塞爾曲線的控制點座標{cp1x,cp1y} 控制點座標{cp2x,cp2y} 終點座標{x,y}
    CGContextAddCurveToPoint(context, 100.0, 0.0, 200.0, 300.0, (rect.size.width - 10.0), 100.0);
    // 繪製前設定顏色
    // 方法1-只有邊框顏色
//    [[UIColor blueColor] setStroke];
//    CGContextStrokePath(context);
    // 方法2-邊框和填充顏色
    [[UIColor greenColor] setStroke];
    [[UIColor yellowColor] setFill];
    CGContextDrawPath(context, kCGPathFillStroke);
}

(5)漸變背景顏色

// 漸變
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextClip(context);
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
    CGFloat colors[] = {
        204.0 / 255.0, 224.0 / 255.0, 244.0 / 255.0, 1.00,
        29.0 / 255.0, 156.0 / 255.0, 215.0 / 255.0, 1.00,
        0.0 / 255.0,  50.0 / 255.0, 126.0 / 255.0, 1.00,
    };
    CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, sizeof(colors) / (sizeof(colors[0]) * 4));
    CGColorSpaceRelease(rgb);
    CGContextDrawLinearGradient(context, gradient, CGPointMake(0.0,0.0), CGPointMake(0.0, rect.size.height),
    kCGGradientDrawsBeforeStartLocation);
}