drawRect:自定義view的繪圖

繪圖的步驟:1.獲取上下文 2.創建路徑(描述路徑)3.把路徑添加到上下文4.渲染上下文
為什么要在drawRect里繪圖,只有在這個方法里面才能獲取到跟View的layer相關的圖形上下文
什么時候調用:當這個view要現實的時候才會調用drawRect繪制圖形,一般在viewWillAppear之后(調用一次跟viewDidLoad一樣加載的時候調用一次,自己可以實現調用)
1.自己創建路徑的方法

- (void)drawRect:(CGRect)rect
{
    //1.獲取圖形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //2.描述路徑
    //創建路徑
    CGMutablePathRef path=CGPathCreateMutable();
    //設置起點 path:給哪個路徑設置起點
    CGPathMoveToPoint(path, NULL, 50, 50);
    //添加一根線到某個點
    CGPathAddLineToPoint(path, NULL, 100, 100);
    //3.把路徑添加到上下文
    CGContextAddPath(context, path);
    //4.渲染上下文
    CGContextStrokePath(context);
}

2.用系統的默認路徑繪圖

- (void)drawRect:(CGRect)rect
{
    //獲取圖形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //描述路徑
    CGContextMoveToPoint(context, 50, 50);
    CGContextAddLineToPoint(context, 100, 100);
    //默認下一根線的起點就是上一根線的終點
    CGContextAddLineToPoint(context, 120, 100);
    //多根線 但是是一個路徑不能分別設置顏色(可以用自創建路徑或UIBezierPath)
    CGContextMoveToPoint(context, 50, 50);
    CGContextAddLineToPoint(context, 100, 100);
    
    
    //繪制曲線
    CGContextMoveToPoint(context, 80, 50);
    
    //cpx cpy :控制點的x,y
    //    CGContextAddQuadCurveToPoint(<#CGContextRef  _Nullable c#>, <#CGFloat cpx#>, CGFloat cpy, <#CGFloat x#>, <#CGFloat y#>)
    CGContextAddQuadCurveToPoint(context, 150, 20, 120, 100);
    
    
    
    
    //設置繪圖狀態,一定要在渲染之前
    //顏色
    [[UIColor greenColor] setStroke];
    //線寬
    CGContextSetLineWidth(context, 10);
    //設置連接樣式
    CGContextSetLineJoin(context, kCGLineJoinBevel);
    //設置頂角樣式
    CGContextSetLineCap(context, kCGLineCapRound);
    //渲染上下文
    CGContextStrokePath(context);
}

3.用UIBezierPath 繪圖

- (void)drawRect:(CGRect)rect
{
    //UIKit 已經封裝了一些繪圖的功能
    //貝塞爾路徑
    //創建路徑
    UIBezierPath*path=[UIBezierPath bezierPath];
    //設置起點
    [path moveToPoint:CGPointMake(50, 50)];
    //添加一根線到某個點
    [path addLineToPoint:CGPointMake(100, 100)];
    
    path.lineWidth=10;
    [[UIColor greenColor]set];
    path.lineCapStyle=kCGLineCapRound;
    path.lineJoinStyle=kCGLineJoinBevel;
    //繪制路徑
    [path stroke];
    
    //創建路徑
    UIBezierPath*path1=[UIBezierPath bezierPath];
    //設置起點
    [path1 moveToPoint:CGPointMake(80, 50)];
    //添加一根線到某個點
    [path1 addLineToPoint:CGPointMake(130, 100)];
    
    path1.lineWidth=10;
    [[UIColor blueColor]set];
    path1.lineCapStyle=kCGLineCapRound;
    path1.lineJoinStyle=kCGLineJoinBevel;
    //繪制路徑
    [path1 stroke];
    
    //圓弧
    //Center:圓心
    //startAngle:開始弧度
    //clockwise:YES:順時針 NO:逆時針
    UIBezierPath *path3=[UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
    //添加一根線到圓心
    [path3 addLineToPoint:CGPointMake(100, 100)];
    //封閉路徑,從路徑的終點到起點
    //    [path3 closePath];
    //    [path3 stroke];
    
    //填充:必須是一個完整的封閉路徑,默認就會自動關閉路徑
    [path3 fill];

}

自己實現圓形進度條

#import <UIKit/UIKit.h>

@interface DrawView : UIView
@property(nonatomic,assign)CGFloat progress;
@end
-(void)setProgress:(CGFloat)progress
{
    _progress=progress;
    //重繪 ,系統會先創建與view相關的上下文,然后再調用
    [self setNeedsDisplay];
}
//注意:drawRect不能手動調用,因為圖形上下文我們自己創建不了,只能由系統幫我們創建,并且傳遞給我們

- (void)drawRect:(CGRect)rect
{
    CGFloat radius=rect.size.width*0.5;
    CGPoint center=CGPointMake(radius, radius);
    //-M_PI_2 開始弧度圓的定點
    //_progress*M_PI*2  _progress百分多少 M_PI*2 360度
    CGFloat endA = -M_PI_2 + _progress*M_PI*2;
    UIBezierPath*path=[UIBezierPath bezierPathWithArcCenter:center radius:radius-2 startAngle:-M_PI_2 endAngle:endA clockwise:YES];
    [path stroke];
}

畫餅狀圖

- (void)drawRect:(CGRect)rect
{
    NSArray*arr=@[@36,@34,@30];
    CGFloat radius=rect.size.width*0.5;
    CGPoint center=CGPointMake(radius, radius);
    CGFloat startA=0;
    CGFloat endA=0;
    CGFloat angle=0;
    for (int i=0; i<arr.count; i++)
    {
        startA=endA;
        angle=[arr[i] doubleValue]/100.0*M_PI*2;
        endA=startA+angle;
        UIBezierPath*path=[UIBezierPath bezierPathWithArcCenter:center radius:radius-2 startAngle:startA endAngle:endA clockwise:YES];
        [path addLineToPoint:center];
        [[self colorRandom] set];
        [path fill];
    }
}
-(UIColor*)colorRandom
{
    CGFloat r=arc4random_uniform(256)/255.0;
    CGFloat g=arc4random_uniform(256)/255.0;
    CGFloat b=arc4random_uniform(256)/255.0;
    return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
}

畫柱狀圖

- (void)drawRect:(CGRect)rect
{
    NSArray*arr=@[@36,@34,@30];
    CGFloat w=rect.size.width/(2*arr.count-1);
    CGFloat x=0;
    CGFloat y=0;
    CGFloat h=0;
    for (int i=0; i<arr.count; i++)
    {
        x=2*w*i;
        h=[arr[i] floatValue]/100.0 *rect.size.height;
        y=rect.size.height-h;
        UIBezierPath*path=[UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];
        [[self colorRandom] set];
        [path fill];
    }
}
-(UIColor*)colorRandom
{
    CGFloat r=arc4random_uniform(256)/255.0;
    CGFloat g=arc4random_uniform(256)/255.0;
    CGFloat b=arc4random_uniform(256)/255.0;
    return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
}

NSTimer

//NSTimer很少用于繪畫,因為調度優先級比較低,并不會準時調用
-(void)awakeFromNib
{
//    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
    CADisplayLink*link=[CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];
    //想讓定時器工作,必須得要把它添加到主運行循環
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
//在繪圖當中, 我們一般使用CADisplayLink.因為他和setNeedsDisplay調用時機是一樣的,都是當下一次屏幕刷新的時候調用.
//CADisplayLink:每次屏幕刷新的時候就會調用,屏幕一般一秒刷新60次
-(void)timeChange
{
    //注意:這個方法并不會馬上調用drawRect,其實這個方法只是給當前控件添加刷新的標記,等下一次屏幕刷新的時候才會調用drawRect
    [self setNeedsDisplay];
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,084評論 2 375

推薦閱讀更多精彩內容

  • Core Graphics Framework是一套基于C的API框架,使用了Quartz作為繪圖引擎。它提供了低...
    ShanJiJi閱讀 1,556評論 0 20
  • Quartz2D以及drawRect的重繪機制字數1487 閱讀21 評論1 喜歡1一、什么是Quartz2D Q...
    PurpleWind閱讀 786評論 0 3
  • 本章中迄今為止的繪制實施例中大多會產生一個UIImage對象,主要是通過調用UIGraphicsBeginImag...
    shenzhenboy閱讀 1,377評論 0 4
  • 一家制造電冰箱的大公司的經理來到警察局報案:“有個20多歲的年輕人冒充我公司的推銷員,幾天便賺了十幾萬美元,...
    卓奇閱讀 148評論 0 0
  • 1)搶紅包后 貓大神說:搶了紅包后,基本的素質是要謝謝發紅包的。 老妖婆立刻發圈:搶了紅包,一聲不吭,跟沒搶一樣淡...
    死侃腦殼的老妖婆閱讀 450評論 14 10