// 什么時候調(diào)用:當(dāng)前控件即將顯示的時候才會調(diào)用這個方法繪制 // 作用:繪制內(nèi)容,以后只要想在一個view中繪制內(nèi)容,必須在drawRect里面繪制 - (void)drawRect:(CGRect)rect { // 繪制曲線 // 1.獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.拼接路徑 UIBezierPath *path = [UIBezierPath bezierPath]; // 設(shè)置起點(diǎn) [path moveToPoint:CGPointMake(10, 125)]; // 描述曲線 [path addQuadCurveToPoint:CGPointMake(240, 125) controlPoint:CGPointMake(125, 240)]; [path addLineToPoint:CGPointMake(10, 125)]; // 3.添加路徑到上下文 CGContextAddPath(ctx, path.CGPath); // 設(shè)置繪圖狀態(tài),一定要再渲染之前 // 設(shè)置顏色 [[UIColor redColor] setStroke]; // 設(shè)置線段的寬度 CGContextSetLineWidth(ctx, 15); // 設(shè)置線段的頂角樣式 CGContextSetLineCap(ctx, kCGLineCaPRound); // 設(shè)置連接樣式 CGContextSetLineJoin(ctx, kCGLineJoinRound); // 4.渲染上下文 CGContextStrokePath(ctx);}
// 繪制兩條路徑的方法- (void)drawTwoLine{ // 1.獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.拼接路徑,一個路徑中可以保存多條線段 UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10, 10)]; [path addLineToPoint:CGPointMake(20, 20)]; // 3.把路徑添加到上下文 CGContextAddPath(ctx, path.CGPath); // 一根線對應(yīng)一個路徑,只要繪制的線不連接,最好使用一根線對應(yīng)一個路徑的方法 path = [UIBezierPath bezierPath]; // 拼接另一根直線 // 默認(rèn)下一根線的起點(diǎn)就是上一根線的終點(diǎn) // 設(shè)置第二根線的起點(diǎn) // [path moveToPoint:CGPointMake(20, 20)]; // 如果想要繪制不連接的線,重新設(shè)置起點(diǎn) [path moveToPoint:CGPointMake(50, 50)]; [path addLineToPoint:CGPointMake(20, 200)]; // 3.把路徑添加到上下文 CGContextAddPath(ctx, path.CGPath); // 4.渲染上下文 CGContextStrokePath(ctx);}
// 畫圓弧 // Center圓心 // radius:半徑 // startAngle起始角度 // endAngle:結(jié)束角度 // clockwise:Yes 順時針 No逆時針 CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5); UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:NO]; [path1 stroke];
// 畫扇形 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; [path addLineToPoint:center]; [path addLineToPoint:CGPointMake(self.bounds.size.height * 0.5 + 100, self.bounds.size.height * 0.5)]; // 關(guān)閉路徑:從路徑的終點(diǎn)連接到起點(diǎn) [path closePath]; // 設(shè)置填充顏色 [[UIColor redColor] setFill]; // 設(shè)置描邊顏色 [[UIColor greenColor] setStroke]; // [path stroke]; // 如果路徑不是封閉的,默認(rèn)會關(guān)閉路徑 [path fill];
#import "PieView.h"@implementation PieView// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ //重繪 [self setNeedsDisplay];}- (void)drawRect:(CGRect)rect { // Drawing code NSArray *data = @[@25,@25,@20,@30]; //圓心 CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5); //角度 CGFloat radius = self.bounds.size.width * 0.5; CGFloat startA = 0; CGFloat endA = 0; CGFloat angle = 0; for (NSNumber *num in data) { // 畫一個扇形 startA = endA; angle = [num intValue] / 100.0 * M_PI * 2; endA = startA + angle; UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES]; [path addLineToPoint:center]; // set:同時設(shè)置描邊和填充顏色 [[self randomColor] set]; [path fill]; }}// 隨機(jī)顏色- (UIColor *)randomColor{ 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];}@end效果圖:
- (void)drawRect:(CGRect)rect { NSString *str = @"hello!"; // Attributes:屬性 // 給一個字符串添加屬性,可以叫富文本,顏色,字體大小,空心,陰影 // 利用這個屬性字典給文本添加屬性 NSMutableDictionary *strAttr = [NSMutableDictionary dictionary]; // key,value // 如何找到設(shè)置文本的屬性key // 描述了字體 strAttr[NSFontAttributeName] = [UIFont boldSystemFontOfSize:50]; // 設(shè)置描邊的顏色和寬度 strAttr[NSStrokeWidthAttributeName] = @1; strAttr[NSStrokeColorAttributeName] = [UIColor redColor]; NSShadow *shadow = [[NSShadow alloc] init]; shadow.shadowColor = [UIColor yellowColor]; shadow.shadowOffset = CGSizeMake(10, 10); shadow.shadowBlurRadius = 5; // 陰影 strAttr[NSShadowAttributeName] = shadow; // 文字顏色 strAttr[NSForegroundColorAttributeName] = [UIColor redColor]; [str drawAtPoint:CGPointZero withAttributes:strAttr];} 效果圖:
#import "SnowView.h"@implementation SnowView- (void)awakeFromNib{ // 設(shè)置定時器// [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; // 0.1 setNeedsDisplay 綁定一個標(biāo)識,等待下次刷新的時候才會調(diào)用drawRect方法 // 0.15 屏幕的刷新時間 // 定時器 // 每次屏幕刷新的時候就會調(diào)用,屏幕一秒刷新60次 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)]; // 只要把定時器添加到主運(yùn)行循環(huán)就能自動執(zhí)行 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; // setNeedsDisplay:底層并不會馬上調(diào)用drawRect,只會給當(dāng)前的控件綁定一個刷新的標(biāo)識,每次屏幕刷新的時候,就會把綁定了刷新(重繪)標(biāo)識的控件重新刷新(繪制)一次,就會調(diào)用drawRect去重繪 // 如果以后每隔一段時間需要重繪,一般不使用NSTimer,使用CADisplayLink,不會刷新的時候有延遲}// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect { // Drawing code static CGFloat snowY = 0; UIImage *image = [UIImage imageNamed:@"雪花"]; [image drawAtPoint:CGPointMake(0, snowY)]; snowY += 10; if (snowY > rect.size.height) { snowY = 0; }}
效果圖:
#import "DrawView.h"@implementation DrawView// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect { // Drawing code // 1.獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.拼接路徑 UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10, 125)]; [path addLineToPoint:CGPointMake(240, 125)]; // 3.把路徑添加到上下文 CGContextAddPath(ctx, path.CGPath); // 保存當(dāng)前上下文的默認(rèn)狀態(tài) CGContextSaveGState(ctx); // 設(shè)置狀態(tài) [[UIColor redColor] set]; CGContextSetLineWidth(ctx, 20); // 渲染上下文 CGContextStrokePath(ctx); // 創(chuàng)建第二根路徑 path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(125, 10)]; [path addLineToPoint:CGPointMake(125, 240)]; // 添加到上下文 CGContextAddPath(ctx, path.CGPath); // 恢復(fù)下上下文狀態(tài) // 取出之前的保存的狀態(tài)覆蓋掉當(dāng)前的狀態(tài) CGContextRestoreGState(ctx);// [[UIColor blackColor] set];// CGContextSetLineWidth(ctx, 1); // 4.渲染上下文到view的layer // 在渲染之前,系統(tǒng)會查看下上下文的狀態(tài),根據(jù)狀態(tài)去渲染 CGContextStrokePath(ctx);}@end
#import "ViewController.h"@interface ViewController ()@property (nonatomic, weak) UIView *cover;@property (nonatomic, assign) CGPoint oriP;@property (weak, nonatomic) IBOutlet UIImageView *imageView;@property (weak, nonatomic) IBOutlet UIView *view1;@end@implementation ViewController- (UIView *)cover{ if (_cover == nil) { UIView *view = [[UIView alloc] init]; view.backgroundColor = [UIColor blackColor]; view.alpha = 0.5; _cover = view; [self.view addSubview:view]; } return _cover;}- (IBAction)pan:(UIPanGestureRecognizer *)sender { // 獲取下當(dāng)前的觸摸 CGPoint curP = [sender locationInView:_imageView]; if (sender.state == UIGestureRecognizerStateBegan) { // 記錄下一開始的位置 _oriP = curP; } // 計(jì)算下黑色蒙版的frame CGFloat w = curP.x - _oriP.x; CGFloat h = curP.y - _oriP.y; self.cover.frame = CGRectMake(_oriP.x, _oriP.y, w, h); if (sender.state == UIGestureRecognizerStateEnded) { // 手指抬起 // 裁剪圖片,生成一張新圖片 // 開啟位圖上下文 UIGraphicsBeginImageContextWithOptions(_imageView.bounds.size, NO, 0); // 設(shè)置裁剪區(qū)域 UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.cover.frame]; [path addClip]; // 繪制圖片 [_imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; // 生成圖片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 關(guān)閉上下文 UIGraphicsEndImageContext(); _imageView.image = image; [self.cover removeFromSuperview]; }}@end效果圖:截屏前
效果圖:截屏后
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController// 只要用戶手指在圖片上拖動.就會調(diào)用- (IBAction)pan:(UIPanGestureRecognizer *)sender { // 拖動的時候,擦除圖片的某一部分 // 獲取手指的觸摸點(diǎn) CGPoint curP = [sender locationInView:sender.view]; // 計(jì)算擦除的frame CGFloat wh = 30; CGFloat x = curP.x - wh * 0.5; CGFloat y = curP.y - wh * 0.5; CGRect frame = CGRectMake(x, y, wh, wh); // 開啟位圖上下文 UIGraphicsBeginImageContextWithOptions(sender.view.bounds.size, NO, 0); // 獲取當(dāng)前的上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 把控件上的內(nèi)容渲染到上下文 [sender.view.layer renderInContext:ctx]; // 清除上下文中某一部分的內(nèi)容 CGContextClearRect(ctx, frame); // 生成一張新的圖片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 關(guān)閉上下文 UIGraphicsEndImageContext(); // 重新顯示到UIImageView UIImageView *imageV = (UIImageView *)sender.view; imageV.image = image;}@end效果圖:擦除前:效果圖:擦除部分后:
新聞熱點(diǎn)
疑難解答
圖片精選