
我們可以在UIView(UIViewRendering)的方法- (void)drawRect:(CGRect)rect;中去繪制一些我們所需要的圖形,如虛線、圓形、方形以及曲線等等圖形。但在使用drawRect時(shí)有一些需要注意的事項(xiàng):
- 我們只能在繼承了
UIView的子類中通過重寫drawRect方法來繪制圖形。 - 如果需要繪制圖形的子類直接繼承自
UIView,則子類的drawRect方法中不需要調(diào)用父類方法[super drawRect:rect];。如果子類繼承自其他繼承UIView的View類,則drawRect方法中需要調(diào)用父類方法[super drawRect:rect];。 -
drawRect方法不能手動(dòng)直接調(diào)用,我們可以通過調(diào)用其他方法來實(shí)現(xiàn)drawRect方法的調(diào)用。如:在子類初始化時(shí)調(diào)用- (instancetype)initWithFrame:(CGRect)frame方法,且frame不為CGRectZero時(shí)。 - 我們可以調(diào)用
setNeedsDisplay()方法或setNeedsDisplayInRect方法,但是該方法不會(huì)自己調(diào)用drawRect方法,而是會(huì)標(biāo)記視圖,并在下一次循環(huán)更新的時(shí)候讓視圖通過drawRect來進(jìn)行重繪,前提是rect不為CGRectZero。
一、虛線
繪制虛線的基本思路:
- 通過
UIGraphicsGetCurrentContext來獲取需要處理的上下文線條。
CGContextRef context = UIGraphicsGetCurrentContext();
- 通過
CGContextSetLineWidth來設(shè)置線條的寬度。
CGContextSetLineWidth(context, 2.0);
- 通過
CGContextSetStrokeColorWithColor或者CGContextSetRGBStrokeColor來設(shè)置線條的顏色。
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
- 通過
CGContextSetLineDash來設(shè)置虛線點(diǎn)的大小以及虛線點(diǎn)間隔大小。其中{3, 1}表示先畫3個(gè)實(shí)點(diǎn)再畫1個(gè)虛點(diǎn),即實(shí)點(diǎn)多虛點(diǎn)少表示虛線點(diǎn)大且間隔小,實(shí)點(diǎn)少虛點(diǎn)多表示虛線點(diǎn)小且間隔大。最后的參數(shù)1代表排列的個(gè)數(shù)。
CGFloat dashArray[] = {3, 1};
CGContextSetLineDash(context, 1, dashArray, 1);
- 然后設(shè)置虛線的起點(diǎn)和終點(diǎn)坐標(biāo),并且有兩種方法。第一種是通過
CGContextMoveToPoint設(shè)置線條的起點(diǎn)坐標(biāo)(CGFloat x1, CGFloat y1),通過CGContextAddLineToPoint設(shè)置線條的終點(diǎn)坐標(biāo)(CGFloat x2, CGFloat y2)。第二種設(shè)置坐標(biāo)點(diǎn)數(shù)組,通過CGContextAddLines添加坐標(biāo)點(diǎn)數(shù)組。
第一種:
CGContextMoveToPoint(context, K_PDD_WIDTH, K_HEIGHT*3);
CGContextAddLineToPoint(context, (rect.size.width - K_PDD_WIDTH), K_HEIGHT*3);
第二種:
CGPoint aPoints[2];
aPoints[0] = CGPointMake(K_PDD_WIDTH, K_HEIGHT);
aPoints[1] = CGPointMake((rect.size.width - K_PDD_WIDTH), K_HEIGHT);
CGContextAddLines(context, aPoints, 2);
- 最后通過
CGContextStrokePath來繪制兩點(diǎn)之間的路徑。
CGContextStrokePath(context);
完整代碼:
#define K_HEIGHT 100.0
#define K_PDD_WIDTH 20.0
- (void)drawRect:(CGRect)rect {
//獲得處理的上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//線條寬
CGContextSetLineWidth(context, 2.0);
//線條顏色
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
//畫虛線
CGFloat dashArray[] = {3, 1};//表示先畫3個(gè)實(shí)點(diǎn)再畫1個(gè)虛點(diǎn),即實(shí)點(diǎn)多虛點(diǎn)少表示虛線點(diǎn)大且間隔小,實(shí)點(diǎn)少虛點(diǎn)多表示虛線點(diǎn)小且間隔大
CGContextSetLineDash(context, 1, dashArray, 1);//最后的參數(shù)1代表排列的個(gè)數(shù)
//起點(diǎn)坐標(biāo)
CGContextMoveToPoint(context, K_PDD_WIDTH, K_HEIGHT*3);
//終點(diǎn)坐標(biāo)
CGContextAddLineToPoint(context, (rect.size.width - K_PDD_WIDTH), K_HEIGHT*3);
//繪制路徑
CGContextStrokePath(context);
}
繪制圖像如下:

二、實(shí)線
繪制實(shí)線的思路和虛線的思路基本一樣,主要區(qū)別在于需要去掉繪制虛線方法中設(shè)置虛線點(diǎn)大小的方法CGContextSetLineDash。
完整代碼:(代碼中使用了繪制虛線思路中設(shè)置線條顏色和設(shè)置起點(diǎn)終點(diǎn)坐標(biāo)的第二種方法)
- (void)firstDrawStraightLineWithRect:(CGRect)rect {
//獲得處理的上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//線條寬
CGContextSetLineWidth(context, 1.0);
//線條顏色
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0); //設(shè)置線條顏色第一種方法
//坐標(biāo)點(diǎn)數(shù)組
CGPoint aPoints[2];
aPoints[0] = CGPointMake(K_PDD_WIDTH, K_HEIGHT);
aPoints[1] = CGPointMake((rect.size.width - K_PDD_WIDTH), K_HEIGHT);
//添加線 points[]坐標(biāo)數(shù)組,和count大小
CGContextAddLines(context, aPoints, 2);
//根據(jù)坐標(biāo)繪制路徑
CGContextDrawPath(context, kCGPathStroke);
}
繪制圖像如下:

三、繪制文本
直接上代碼,其中有注釋:
- (void)drawRect:(CGRect)rect {
NSString * text = @"這是一段繪制文本、這是一段繪制文本、這是一段繪制文本、這是一段繪制文本、這是一段繪制文本、這是一段繪制文本、這是一段繪制文本”;
//文本段落樣式
NSMutableParagraphStyle * textStyle = [[NSMutableParagraphStyle alloc] init];
textStyle.lineBreakMode = NSLineBreakByWordWrapping;//結(jié)尾部分的內(nèi)容以……方式省略 ( "...wxyz" ,"abcd..." ,"ab…yz”)
textStyle.alignment = NSTextAlignmentLeft;//文本對(duì)齊方式:(左,中,右,兩端對(duì)齊,自然)
textStyle.lineSpacing = 8; //字體的行間距
textStyle.firstLineHeadIndent = 35.0; //首行縮進(jìn)
textStyle.headIndent = 0.0; //整體縮進(jìn)(首行除外)
textStyle.tailIndent = 0.0; //尾部縮進(jìn)
textStyle.minimumLineHeight = 40.0; //最低行高
textStyle.maximumLineHeight = 40.0; //最大行高
textStyle.paragraphSpacing = 15; //段與段之間的間距
textStyle.paragraphSpacingBefore = 22.0f; // 段首行空白空間
textStyle.baseWritingDirection = NSWritingDirectionLeftToRight; //從左到右的書寫方向
textStyle.lineHeightMultiple = 15;
textStyle.hyphenationFactor = 1; //連字屬性 在iOS,唯一支持的值分別為0和1
//文本屬性
NSMutableDictionary *textAttributes = [[NSMutableDictionary alloc] init];
//段落樣式
[textAttributes setValue:textStyle forKey:NSParagraphStyleAttributeName];
//字體名稱和大小
[textAttributes setValue:[UIFont systemFontOfSize:20.0] forKey:NSFontAttributeName];
//顏色
[textAttributes setValue:[UIColor redColor] forKey:NSForegroundColorAttributeName];
//繪制文字
[text drawInRect:rect withAttributes:textAttributes];
}
繪制圖像如下:

四、繪制圖片
繪制圖片的基本思路:
- 通過
UIGraphicsGetCurrentContext來獲取需要處理的上下文線條。
CGContextRef context = UIGraphicsGetCurrentContext();
- 通過
CGContextSaveGState來保存初始狀態(tài)。
CGContextSaveGState(context);
- 利用
CGContextTranslateCTM來移動(dòng)圖形上下文。
CGContextTranslateCTM(context, 50.0, 80.0);
- 利用
CGContextScaleCTM來縮放圖形上下文。
CGContextScaleCTM(context, 0.9, 0.9);
- 利用
CGContextRotateCTM來進(jìn)行旋轉(zhuǎn)操作。
CGContextRotateCTM(context, M_PI_4 / 4);
- 設(shè)置繪制圖片的尺寸大小。
UIImage *image = [UIImage imageNamed:@"512”];
CGRect rectImage = CGRectMake(0.0, 0.0, rect.size.width, (rect.size.width*image.size.height/image.size.width));
- 設(shè)置繪制圖片展示的三種狀態(tài):
- 在
rect范圍內(nèi)完整顯示圖片:
[image drawInRect:rectImage];
- 圖片上下顛倒:
CGContextDrawImage(context, rectImage, image.CGImage);
- 圖片上下顛倒并拼接填充:
CGContextDrawTiledImage(context, rectImage, image.CGImage);
- 最后恢復(fù)到初始狀態(tài)。
CGContextRestoreGState(context);
完整代碼:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//保存初始狀態(tài)(壓棧操作,保存一份當(dāng)前圖形上下文)
CGContextSaveGState(context);
//圖形上下文移動(dòng){x,y}
CGContextTranslateCTM(context, 50.0, 80.0);
//圖形上下文縮放{x,y}
CGContextScaleCTM(context, 0.9, 0.9);
//旋轉(zhuǎn)
CGContextRotateCTM(context, M_PI_4 / 4);
//需要繪制的圖片
UIImage *image = [UIImage imageNamed:@"512”];
CGRect rectImage = CGRectMake(0.0, 0.0, rect.size.width, (rect.size.width*image.size.height/image.size.width));
//三種方式繪制圖片
// 1、在rect范圍內(nèi)完整顯示圖片-正常使用
[image drawInRect:rectImage];
// 2、圖片上下顛倒
// CGContextDrawImage(context, rectImage, image.CGImage);
// 3、圖片上下顛倒并拼接填充
// CGContextDrawTiledImage(context, rectImage, image.CGImage);
//恢復(fù)到初始狀態(tài)(出棧操作,恢復(fù)一份當(dāng)前圖形上下文)
CGContextRestoreGState(context);
}
只展示一種繪制圖片:

五、圓形圖片
繪制圓形圖片的基本思路:
- 獲取
UIView的圖形上下文對(duì)象; - 利用
CG_EXTERN void CGContextAddArc(CGContextRef cg_nullable c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)方法在上下文對(duì)象上繪制一個(gè)圓形路徑。其中參數(shù)(x, y)是圓弧的中心;radius是它的半徑;startAngle是與圓弧第一個(gè)端點(diǎn)的夾角;endAngle是到弧的第二個(gè)端點(diǎn)的角度;startAngle和endAngle用弧度表示;如果圓弧是順時(shí)針畫的,clockwise是1,否則是0; - 利用
CGContextClip方法來裁剪出上下文的顯示區(qū)域,即只有在被裁減出的區(qū)域內(nèi)繪制的圖形才會(huì)顯示; - 把圖片繪制到上下文上。
完整代碼:
- (void)drawRect:(CGRect)rect {
//獲取上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//畫一個(gè)上下文顯示的區(qū)域
CGContextAddArc(context, rect.size.width/2, rect.size.height/2, rect.size.width/2, 0, 2 *M_PI, 1);
//裁剪上下文的顯示區(qū)域
CGContextClip(context);
//獲取圖片
UIImage* image1 = [UIImage imageNamed:@"512”];
//繪制到上下文上
[image1 drawInRect:rect];
}
繪制圓角圖片如下:

六、圓形
繪制圓形的思路和繪制圓形圖片一樣,直接上代碼:
#define K_R 150.0
#define K_PDD 10.0
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//背景顏色設(shè)置
[[UIColor greenColor] set];
CGContextFillRect(context, rect);
CGContextSetLineWidth(context, 2.0);
//畫虛線
CGFloat dashArray[] = {3, 1};
CGContextSetLineDash(context, 1, dashArray, 1);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);
CGContextAddArc(context,
K_PDD+K_R/2, K_R*2+20, K_R/2, 0, 2 * M_PI, 0);
CGContextDrawPath(context, kCGPathFillStroke);
}
繪制圖形效果為下圖中左下角圓形圖案:

七、橢圓形
完整代碼:
#define K_H 100.0
#define K_PDD 10.0
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//背景顏色設(shè)置
[[UIColor whiteColor] set];
CGContextFillRect(context, rect);
//實(shí)線橢圓
CGRect rectRing = CGRectMake(K_PDD, K_PDD, (rect.size.width - K_PDD * 2), K_H);
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextAddEllipseInRect(context, rectRing);
CGContextDrawPath(context, kCGPathStroke);
//虛線橢圓
rectRing = CGRectMake(K_PDD, K_H+K_PDD*2, (rect.size.width - K_PDD * 2), K_H);
CGFloat dashArray[] = {2, 6};
CGContextSetLineDash(context, 1, dashArray, 2);
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
//填充顏色
CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);
CGContextAddEllipseInRect(context, rectRing);
CGContextDrawPath(context, kCGPathStroke);
CGContextFillPath(context);
//填充橢圓
rectRing = CGRectMake(K_PDD, K_H*2+K_PDD*3, (rect.size.width - K_PDD * 2), K_H);
CGContextSetLineWidth(context, 1.0);
//填充顏色
CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);
CGContextAddEllipseInRect(context, rectRing);
CGContextFillPath(context);
}
繪制圖形效果如下:

八、扇形
扇形是圓形的一部分,所以在繪制的時(shí)候可以利用CGContextAddArc方法來設(shè)置扇形的圓弧路徑,并添加原點(diǎn)為起始點(diǎn)開始繪制。即設(shè)置為:
CGContextAddArc(context, R, R, R/2, (-60 * M_PI / 180), (-120 * M_PI / 180), 1);
(-60 * M_PI / 180), (-120 * M_PI / 180)為兩個(gè)端點(diǎn)的角度。最后一位參數(shù)表示如果圓弧是順時(shí)針畫的,clockwise是1,否則是0。
完整代碼:
#define K_PDD 10.0
@implementation FanshapedView
- (void)drawRect:(CGRect)rect {
CGFloat R = (CGRectGetWidth(self.frame)-K_PDD*2)/2;
CGContextRef context = UIGraphicsGetCurrentContext();
//背景顏色設(shè)置
[[UIColor whiteColor] set];
CGContextFillRect(context, rect);
//實(shí)線扇形-順時(shí)針-有邊框,有填充
//邊框?qū)挾? CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
CGContextMoveToPoint(context, R, R);
//填充顏色
CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);
CGContextAddArc(context, R, R, R/2, (-60 * M_PI / 180), (-120 * M_PI / 180), 1);//如果圓弧是順時(shí)針畫的,“clockwise”是1,否則是0;
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
//實(shí)線扇形-逆時(shí)針-有邊框,有填充
//邊框?qū)挾? CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
CGContextMoveToPoint(context, R, R*2);
//填充顏色
CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);
CGContextAddArc(context, R, R*2, R/2, (-60 * M_PI / 180), (-120 * M_PI / 180), 0);//如果圓弧是順時(shí)針畫的,“clockwise”是1,否則是0;
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
繪制扇形如下:

九、正方形
繪制正方形的基本思路:
- 獲取
UIView的圖形上下文對(duì)象; - 設(shè)置邊線寬度;
- 可以添加虛線邊框:
CGFloat dashArray[] = {1, 4};
CGContextSetLineDash(context, 1, dashArray, 2);
- 設(shè)置正方形的四個(gè)頂點(diǎn)位置,有三種方法:
- 直接設(shè)置四個(gè)頂點(diǎn):
CGContextMoveToPoint(context, K_X, K_Y);
CGContextAddLineToPoint(context, K_X+K_W, K_Y);
CGContextAddLineToPoint(context, K_X+K_W, K_Y+K_H);
CGContextAddLineToPoint(context, K_X, K_Y+K_H);
CGContextAddLineToPoint(context, K_X, K_Y);
2.利用CGContextAddLines方法:
CGPoint pointsRect[5] = {CGPointMake(K_X, K_Y), CGPointMake(K_X+K_W, K_Y), CGPointMake(K_X+K_W, K_Y+K_H), CGPointMake(K_X, K_Y+K_H), CGPointMake(K_X, K_Y)};
CGContextAddLines(context, pointsRect, 5);
3.利用CGContextAddRect方法設(shè)置Rect大小:
CGContextAddRect(context, CGRectMake(K_X, K_Y, K_W, K_H));
- 使用繪制模式繪制上下文路徑。
CGContextDrawPath(context, kCGPathFillStroke);
完整代碼:
#define K_X CGRectGetWidth(self.frame)/3
#define K_Y 20
#define K_W CGRectGetWidth(self.frame)/3
#define K_H CGRectGetWidth(self.frame)/3
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//背景顏色設(shè)置
[[UIColor whiteColor] set];
CGContextFillRect(context, rect);
//邊框
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGFloat dashArray[] = {1, 4};//表示先畫1個(gè)點(diǎn)再畫4個(gè)點(diǎn)(前者小后者大時(shí),虛線點(diǎn)小且間隔大;前者大后者小時(shí),虛線點(diǎn)大且間隔小)
CGContextSetLineDash(context, 1, dashArray, 2);//其中的2表示dashArray中的值的個(gè)數(shù)
//方法1 正方形起點(diǎn)-終點(diǎn)
// CGContextMoveToPoint(context, K_X, K_Y);
// CGContextAddLineToPoint(context, K_X+K_W, K_Y);
// CGContextAddLineToPoint(context, K_X+K_W, K_Y+K_H);
// CGContextAddLineToPoint(context, K_X, K_Y+K_H);
// CGContextAddLineToPoint(context, K_X, K_Y);
//方法2 正方形起點(diǎn)-終點(diǎn)
CGPoint pointsRect[5] = {CGPointMake(K_X, K_Y), CGPointMake(K_X+K_W, K_Y), CGPointMake(K_X+K_W, K_Y+K_H), CGPointMake(K_X, K_Y+K_H), CGPointMake(K_X, K_Y)};
CGContextAddLines(context, pointsRect, 5);
//方法3 方形起點(diǎn)-終點(diǎn)
// CGContextAddRect(context, CGRectMake(K_X, K_Y, K_W, K_H));
//填充
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
//繪制路徑及填充模式
CGContextDrawPath(context, kCGPathFillStroke);
}
繪制正方形如圖:

十、矩形和菱形
矩形、菱形和正方形繪制方式類似,部分區(qū)別就是:
- 繪制矩形和菱形的四個(gè)頂點(diǎn)坐標(biāo)不同。
- 繪制正方形四個(gè)頂點(diǎn)的三種方法矩形都可以適用,但第三種不適用于菱形。
十一、弧線和曲線
弧線和曲線的區(qū)別是:
- 弧線利用
CGContextAddQuadCurveToPoint方法添加弧線的控制點(diǎn)坐標(biāo)(即弧線起點(diǎn)與弧線相切線和弧線終點(diǎn)與弧線相切線的焦點(diǎn))和終點(diǎn)坐標(biāo)。 - 曲線利用
CGContextAddCurveToPoint方法添加兩個(gè)弧線的控制點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo)。
完整代碼:
#define K_PDD 50.0
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//背景顏色設(shè)置
[[UIColor whiteColor] set];
CGContextFillRect(context, rect);
//弧線
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor orangeColor].CGColor);
//起點(diǎn)
CGContextMoveToPoint(context, K_PDD, K_PDD);
//設(shè)置貝塞爾曲線的控制點(diǎn)坐標(biāo){cp1x,cp1y} 終點(diǎn)坐標(biāo){x,y}
CGContextAddQuadCurveToPoint(context, (rect.size.width/2), K_PDD*4, (rect.size.width - K_PDD), K_PDD*2);
//繪制前設(shè)置邊框和填充顏色
[[UIColor redColor] setStroke];
[[UIColor darkGrayColor] setFill];
CGContextDrawPath(context, kCGPathFillStroke);
//曲線
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
//起點(diǎn)坐標(biāo)
CGContextMoveToPoint(context, K_PDD, K_PDD*8);
//設(shè)置貝塞爾曲線的控制點(diǎn)坐標(biāo){cp1x,cp1y} 控制點(diǎn)坐標(biāo){cp2x,cp2y} 終點(diǎn)坐標(biāo){x,y}
CGContextAddCurveToPoint(context, 100.0, 100.0, 200.0, 500.0, (rect.size.width - 10.0), K_PDD*6);
//繪制前設(shè)置邊框和填充顏色
[[UIColor redColor] setStroke];
[[UIColor darkGrayColor] setFill];
CGContextDrawPath(context, kCGPathFillStroke);
}
繪制弧線和曲線圖像如下:

十二、漸變背景顏色
直接上代碼:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClip(context);
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGFloat colors[] = {
200.0 / 255.0, 224.0 / 255.0, 244.0 / 0.0, 1.00,
100.0 / 255.0, 156.0 / 255.0, 215.0 / 100.0, 1.00,
0.0 / 255.0, 50.0 / 255.0, 126.0 / 200.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);
}
效果:

部分繪制圖形效果請(qǐng)參考完整Demo drawRect繪制圖形