ios里面的繪制,,在UIView中有個自帶的方法- (void)drawRect:(CGRect)rect實現(xiàn),,實現(xiàn)的過程可以跟現(xiàn)實生活中的繪畫過程相對比,,例如如何畫一條直線,,1.要準備一張紙,,用于畫畫;2.要準備一支畫筆,,能選擇筆頭的顏色,花筆的粗細,;3.想好所畫線的起始點,;4。動手畫下來 - (void)drawRect:(CGRect)rect { CGContextRef context=UIGraphicsGetCurrentContext();//設置一個空白view,,準備畫畫 CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);//設置當前筆頭顏色 CGContextSetLineWidth(context, 2.0);//設置當前畫筆粗細 CGContextMoveToPoint(context, 10.0, 30.0);//將花筆移到某點 CGContextAddLineToPoint(context, 300.0, 30.0);//設置一個終點 CGContextStrokePath(context); } 如何畫多條線 第一種方法,,只保存終點,下一個點以之前的點為起點,,如果只有一個點,,什么都沒有,兩個點,,那就是一條線,,三個點就是連著的兩條線。第二種畫法,,保存每條線的起始點,,那么這些線就可以不連續(xù)了。兩個點畫一條線 CGPoint addLines[] = { CGPointMake(10.0, 90.0), CGPointMake(70.0, 60.0), CGPointMake(130.0, 90.0), CGPointMake(190.0, 60.0), }; 第一種畫法用函數(shù)CGContextAddLines(context, addLines, sizeof(addLines)/sizeof(addLines[0])); // Equivalent to MoveToPoint(points[0]); for(i=1; i<count; ++i) AddLineToPoint(points[i]); 第二種畫法用函數(shù)CGContextStrokeLineSegments(context, addLines, sizeof(addLines)/sizeof(addLines[0])); // Equivalent to for(i=0; i<count; i+=2) { MoveToPoint(point[i]); AddLineToPoint(point[i+1]); StrokePath(); } 這是最簡單的直線繪制,,然而在繪制時可能有很多的效果和處理,,線帽和線的連接處處理 可能有人覺得是不是系統(tǒng)自帶的可以劃出這種線條,其實不是,,這種線條是先用粗筆頭畫一條線,,然后在用紅色的細筆頭再畫一根線所成的效果,。這些不是重點。 上圖中如何的區(qū)別在于(1)在直線的兩側(cè)是否添加空白的部分,,第一張圖是添加圓角,,第二張圖是方角,就是矩形,,第三張就是沒有添加,,系統(tǒng)默認情況下(2)還有一個區(qū)別在于在連接處尖角處理,第一張是圓角,,第二張是尖角,,第三張是平行線。 這兩個效果通過兩個函數(shù)設置CGContextSetLineCap(context, cap);這個函數(shù)設置“線帽”,,線的連接處設置語句為CGContextSetLineJoin(context, join);這兩個函數(shù)在系統(tǒng)中允許設置的狀態(tài)都有三種,。 enum CGLineJoin { kCGLineJoinMiter,kCGLineJoinRound,kCGLineJoinBevel };typedef enum CGLineJoin CGLineJoin; enum CGLineCap { kCGLineCapButt, kCGLineCapRound,kCGLineCapSquare };typedef enum CGLineCap CGLineCap; 到這里畫的都是實線,還有一些情況下要畫虛線 CGContextSetLineDash(context, dashPhase, dashPattern, dashCount);這個函數(shù)設置虛線參數(shù),,第一個是畫布,,第二個是在開始畫線時跳過多少個像素。第三個參數(shù)dashPattern是個數(shù)組,,第四個參數(shù)dashCount是指取數(shù)組dashPattern中前多少個元素,。假如說dashPattern[0],dashPattern[1],,dashPattern[2],;分別為10,20,30,,如果設置dashCount為3,則取這三個元素,,那么線條是10像素的實線,20像素的虛線,,30像素的實線,,然后又是10像素的虛線,20像素的實線,,30像素的虛線...如果dashCount為2,則只取前兩個元素循環(huán),。 如何畫長方形 1.CGContextAddRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0));畫一個以(30,30)為起點,,長60,高60畫一個矩形,。這個矩形長高相等,就是正方形,。這個函數(shù)沒有實現(xiàn)畫到畫布上的過程,。 2.要想實現(xiàn),一步畫到畫布上用CGContextStrokeRect(context, CGRectMake(30.0, 120.0, 60.0, 60.0));畫一個矩形邊框,這個方法使用的是默認的筆頭寬度 3.要想每個矩形設置不同的寬度,,就是設置不同的筆頭寬度,,則用 CGContextStrokeRectWithWidth(context, CGRectMake(30.0, 210.0, 60.0, 60.0), 20.0);這個方法。 4.同時畫多個長方形,。CGRect rects[] = { CGRectMake(120.0, 30.0, 60.0, 60.0), CGRectMake(120.0, 120.0, 60.0, 60.0), CGRectMake(120.0, 210.0, 60.0, 60.0), }; CGContextAddRects(context, rects, sizeof(rects)/sizeof(rects[0])); 如何畫橢圓/圓 1.CGContextAddEllipseInRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0));畫一個橢圓,,內(nèi)切于以(30,30)為起點,,長寬為60的矩形,,就是內(nèi)切于正方形,畫出來的就是圓,。 2.CGContextStrokeEllipseInRect(context, CGRectMake(30.0, 120.0, 60.0, 60.0));直接畫一個圓框到畫布上 3.CGContextFillEllipseInRect(context, CGRectMake(30.0, 120.0, 60.0, 60.0));直接畫一個實心圓,,就是填充了顏色的圓到畫布上。 4.畫圓弧的方法 畫弧的兩種方法 1.CGContextAddArc(context, 150.0, 60.0, 30.0, 0.0, M_PI*2.0, false);這個方法不會直接畫到畫布上,,這個方法是以(150,,60)為圓心,30為半徑,,開始弧度為0,結束弧度為2PI畫圓,,畫弧也可以用這個方 法。最后一個參數(shù) 0為順時針,,1為逆時針 2.CGPoint p[3] = { CGPointMake(210.0, 30.0), CGPointMake(210.0, 60.0), CGPointMake(240.0, 60.0), }; CGContextMoveToPoint(context, p[0].x, p[0].y); CGContextAddArcToPoint(context, p[1].x, p[1].y, p[2].x, p[2].y, 30.0); 第二種畫法,,這種方法其實不是那么好懂,,原理大概是先把筆頭移到210,,30,然后畫兩條切線,,點(210,,30)和點(210,60)畫一條,,點(210,,60)和(240,60)畫一條,。然后根據(jù)半徑確定圓心,,然后畫弧,根據(jù)點的坐標,,弧的方向基本可以確定,。這個方法只能畫90度的圓弧,其他角度的圓弧沒法畫成,。如果畫不成圓弧,,當然也就沒有圓心這個說法。 CGRect rrect = CGRectMake(210.0, 90.0, 60.0, 60.0); CGFloat radius = 10.0; CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); CGContextMoveToPoint(context, minx, midy); CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); CGContextClosePath(context); CGContextDrawPath(context, kCGPathFillStroke); 畫曲線 三次曲線函數(shù)void CGContextAddCurveToPoint ( CGContextRef c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y);// cp1x控制點1 x坐標//cp1y控制點1 y坐標//cp2x控制點2 x坐標// cp2y控制點2 y坐標//x直線的終點 x坐標//y直線的終點 y坐標 上面那個圖的代碼如下 CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); CGContextSetLineWidth(context, 2.0); // Draw a bezier curve with end points s,e and control points cp1,cp2,,畫白色曲線 CGPoint s = CGPointMake(30.0, 120.0); CGPoint e = CGPointMake(300.0, 120.0); CGPoint cp1 = CGPointMake(120.0, 30.0); CGPoint cp2 = CGPointMake(210.0, 210.0); CGContextMoveToPoint(context, s.x, s.y); CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y); CGContextStrokePath(context); // Show the control points.畫紅色線條 CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextMoveToPoint(context, s.x, s.y); CGContextAddLineToPoint(context, cp1.x, cp1.y); CGContextMoveToPoint(context, e.x, e.y); CGContextAddLineToPoint(context, cp2.x, cp2.y); CGContextStrokePath(context); 通過上面的圖看出曲線是相切于兩條直線的,,兩條直線就是從點s到cp1,e到cp2;起點和終點是s和e,,然后根據(jù)cp1和cp2控制形狀,。 假如第二個控制點(cp2x,cp2y)比(cp1x,cp1y) 更接近current point,,那么會形成一個封閉的曲線 二次曲線函數(shù)void CGContextAddQuadCurveToPoint ( CGContextRef c, CGFloat cpx, CGFloat cpy, CGFloat x, CGFloat y);// cpx控制點 x坐標,,//cpy控制點 y坐標//直線的終點 x坐標//直線的終點 y坐標,; CGPoint s = CGPointMake(30.0, 120.0); CGPoint e = CGPointMake(300.0, 120.0); CGPoint cp1 = CGPointMake(120.0, 30.0); CGContextMoveToPoint(context, s.x, s.y); CGContextAddQuadCurveToPoint(context, cp1.x, cp1.y, e.x, e.y); CGContextStrokePath(context); // Show the control point.畫紅色的直線 CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextMoveToPoint(context, s.x, s.y); CGContextAddLineToPoint(context, cp1.x, cp1.y); CGContextStrokePath(context);CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); 如何畫多邊形和五角星 如何畫出上面那些圖形,,在實現(xiàn)是實際上是畫的線條然后弄成閉合,實現(xiàn)的那些效果,。要實現(xiàn)那些邊,,要知道那些線的起始點坐標,如何計算坐標,,可以在草稿上圍繞這那些圖形畫一個圓,,然后畫每條邊到圓心的虛線,然后畫一條經(jīng)過圓心的水平線作為X軸,,根據(jù)你圓心的坐標和半徑長度還有三角形的sin,,cos運算就可以表示出直線的起始點。要實現(xiàn)五角星,,其實只需要畫四條線就可以,,如上圖。 center = CGPointMake(90.0, 90.0); CGContextMoveToPoint(context, center.x, center.y + 60.0); for(int i = 1; i < 5; ++i) { CGFloat x = 60.0 * sinf(i * 4.0 * M_PI / 5.0); CGFloat y = 60.0 * cosf(i * 4.0 * M_PI / 5.0); CGContextAddLineToPoint(context, center.x + x, center.y + y); } // And close the subpath. CGContextClosePath(context); CGContextDrawPath(context, drawingMode); 如何把圖片畫上去 CGImageRef image; NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"Apple.png" ofType:nil]; UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; image = CGImageRetain(img.CGImage); CGRect imageRect; imageRect.origin = CGPointMake(8.0, 8.0);//設置第一張圖的位置,,右圖中imageRect.origin = CGPointMake(32.0, 112.0); imageRect.size = CGSizeMake(64.0, 64.0); CGContextDrawImage(context, imageRect, image); 首先看兩張圖片,左邊的圖片是原圖大小,,正立,,右圖上方那單獨圖片是通過以上代碼畫出來的,但是是一個倒立的圖片,,為什么會倒立,,是因為繪制的Quartz框架是以手機屏幕左下方為坐標(0,0)點,,而view是以左上方為坐標(0,,0)點。第二點,,原圖大小與畫到畫布上的大小無關,,也就是說imageRect.size設置的大小不管原圖多大,也就可能會發(fā)生失真的問題,,結果是會按程序設置的大小畫,,方便排版。第三點,,右圖中無限多個圖片在視圖中,,是平鋪方式繪制的。 CGContextClipToRect(context, CGRectMake(0.0, 80.0, self.bounds.size.width, self.bounds.size.height))); //設置平鋪區(qū)域的大小 CGContextDrawTiledImage(context, imageRect, image.CGImage); //以平鋪的方式繪制 第四點,,在圖中有個加紅色的圖片,,這個功能其實很有用處,在顯示QQ頭像下線加灰色時可以用這個辦法,,其實代碼很簡單,, CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5); CGContextFillRect(context, imageRect); 想到什么效果可以用到哪一類效果,這是開發(fā)者的思維,,平時多注意,。 如何設置一個顏色漸變的view 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,self.frame.size.height), kCGGradientDrawsBeforeStartLocation); 做一個簡單的畫板 源碼下載鏈接,,點擊下載 可以設置粗細和顏色的畫板代碼 在touchesBegan方法中加入[self touchesMoved:touches withEvent:event];這句,,是為了點擊時就畫一個點 在代碼中求出了中間點,也不是非要用中間點,,我試過,,但是用中間理論上可能更準確,其實可以忽略不計。 CGMutablePathRef path = CGPathCreateMutable();CGPathCreateMutable主要是為動畫設置移動路徑的,。 CGPathMoveToPoint設置移動到某點,,這個方法之前的點不會建立一條直線 CGPathAddQuadCurveToPoint以二次曲線的方式移動 CGPathGetBoundingBox得到占用的區(qū)域的大小 UIGraphicsBeginImageContext創(chuàng)建一個基于位圖的上下文,并將其設置為上下文 [self.layer renderInContext:context],;將view畫到畫布上 UIGraphicsGetImageFromCurrentImageContext從畫布上獲取到view [self setNeedsDisplayInRect:drawBox];刷新所設置的drawBox區(qū)域的視圖 ios如何做一個類似360掃描的檢測,,類360檢測效果 當看到這個需求的時候,第一感覺是東西多,,然后先分一下,,哪些是動的,哪些是不動的,,整個汽車,,背景,玻璃面板都是不動的,,玻璃框中的視圖是需要變化的,,然后分清這個圖有幾層,哪個視圖應該在哪個視圖上面,,然后和先做一個繪制圓形的demo,,繪制圓形代碼下載 完整實現(xiàn)代碼 CGContextClearRect 設置一個清除區(qū)域,可用于橡皮擦擦去數(shù)據(jù)的功能 |
|
來自: plumbiossom > 《代碼》