Quartz2D
- 在 - (void)drawRect:(CGRect)rect方法里面實現添加一個根線
- 基本步驟
- 1.獲取上下文->2.描述路徑->3.把路徑添加到上下文->4.把上下文的內容渲染到View的layer.
//作用:繪圖(該方法是UIView的方法,所以凡是UIView的子類都擁有,都可以實現)
//什么時候調用:(系統自動調用)當View顯示的時候調用
//參數:當前View的bounds
//在drawRect系統已經自動創建了一個跟當前View相關聯的上下文
- (void)drawRect:(CGRect)rect {
//1.獲取跟View相關聯的上下文(uigraphics開頭)
// CGContextRef ctx = UIGraphicsGetCurrentContext();
//2.描述路徑
// UIBezierPath *path = [UIBezierPath bezierPath];
//設置起點
// [path moveToPoint:CGPointMake(50, 250)];
//添加一根曲線到某個點
// [path addQuadCurveToPoint:CGPointMake(250, 250) controlPoint:CGPointMake(80, 100)];
//3.把路徑添加到上下文
// CGContextAddPath(ctx, path.CGPath);
//4.把上下文內容渲染到View上.
// CGContextStrokePath(ctx);
//在drawRect系統已經自動創建了一個跟當前View相關聯的上下文,所以只要添加上路徑就可以了
UIBezierPath *path = [UIBezierPath bezierPath];
//設置起點
[path moveToPoint:CGPointMake(50, 150)];
//添加一根線到某個點
[path addLineToPoint:CGPointMake(250, 50)];
[path setLineWidth:10];
[path setLineCapStyle:kCGLineCapRound];
[[UIColor redColor] set];
[path stroke];
// 自定義的方法中是實現添加一根線
// [self drawLine];
}
//畫直線(也可以畫曲線)
- (void)drawLine {
//1.獲取跟View相關聯的上下文(uigraphics開頭)
CGContextRef context = UIGraphicsGetCurrentContext();
//2.描述路徑
//一條路徑可以繪制多條線
UIBezierPath *path = [UIBezierPath bezierPath];
//設置起點
[path moveToPoint:CGPointMake(50, 150)];
//添加一根線到某個點
[path addLineToPoint:CGPointMake(250, 50)];
//畫第二根線
//[path moveToPoint:CGPointMake(50, 250)];
//[path addLineToPoint:CGPointMake(250, 100)];
//把上一條路徑的終點,當作是下一個路徑的起點
[path addLineToPoint:CGPointMake(50, 250)];
//設置上下文的狀態
// 設置線寬
CGContextSetLineWidth(context, 10);
//設置線的連接樣式
CGContextSetLineJoin(context, kCGLineJoinMiter);
//設置線的頂角樣式
CGContextSetLineCap(context, kCGLineCapRound);
//設置顏色(Sets the fill and stroke colors in the current drawing context.)
[[UIColor redColor] set];
//3.把路徑添加到上下文
//UIBezierPath->UIKit --> CGPathRef->CoreGraphics
CGContextAddPath(context, path.CGPath);
//4.把上下文當中繪制的內容渲染到跟View關聯的layer.(stroke ,fill)
CGContextStrokePath(context);
}
- (void)drawRect:(CGRect)rect {
//描述一個橢圓
//UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 200, 200)];
//繪制路徑
//[[UIColor yellowColor] set];
//[path fill];
//畫弧
//Center:弧所在的圓心
//radius:圓的半徑
//startAngle:開始角度,圓的最右側為0度
//endAngle:截至角度,向下為正,向上為負.
//clockwise:時針的方向,yes:順時針 no:逆時針
//CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);
CGFloat radius = rect.size.width * 0.5 - 10;
CGFloat startA = 0;
CGFloat endA = -M_PI_2;
//畫弧的路徑
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.center radius:radius startAngle:startA endAngle:endA clockwise:NO];
//畫扇形
//添加一根線到圓心
[path addLineToPoint:self.center];
//關閉路徑(自動的從路徑的終點連接到路徑的起點)
//[path closePath];
[[UIColor redColor] set];
//使用fill在填充之前,自動的關閉路徑
[path fill];
//1.獲取上下文->2.描述路徑->3.把路徑添加到上下文->4.把上下文的內容渲染到View的layer.
}
//畫矩形
- (void)drawRect {
//1.獲取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//2.描述路徑
//矩形
//UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
//畫圓角矩形
//cornerRadius:圓角半徑
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 200) cornerRadius:100];
//3.把路徑添加到上下文
CGContextAddPath(ctx, path.CGPath);
[[UIColor redColor] set];
//4.把上下文的內容渲染到View的layer.
//CGContextStrokePath(ctx);
CGContextFillPath(ctx);
}
b貝曲爾曲線畫餅圖
- 步驟
- 設置圓心的位置center(CGPoint)
- 設置開始的角度startAngle(CGFloat),這其中涉及到數字轉換為角度(num.intValue / 100.0 * M_PI * 2;)
- 使用貝曲爾曲線畫圓
- (void)drawRect:(CGRect)rect {
// Drawing code
NSArray *dataArray = @[@25,@25,@50];
//畫弧
CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * .5);
CGFloat radius = rect.size.width * 0.5 - 10;
// 初始化角度
CGFloat startA = 0;
CGFloat angle = 0;
CGFloat endA = 0;
// 從數組中讀取到每個圓所占的比例
for (NSNumber *num in dataArray) {
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];
// 曲線的顏色
[[self randomColor] set];
//添加一根線到圓心
[path addLineToPoint:center];
// 自動閉合
[path fill];
}
}
雪花效果
- (void)awakeFromNib {
//添加定時器
//[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(update) userInfo:nil repeats:YES];
//什么時候調用指定的方法?
//當下一次屏幕刷新時調用(屏幕每一秒刷新60)
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
//想要讓CADisplayLink工作, 必須得要添加到主運行循環當中.
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
//setNeedsDisplay底層會調用drawRect,并不是立馬調用的.只是設了一個調用的標志.
//等下一次屏幕刷新時才去調用drawRect
}
static int _snowY = 0;
- (void)update {
_snowY += 10;
if (_snowY > self.bounds.size.height) {
_snowY = 0;
}
//重繪
[self setNeedsDisplay];
}
// 三個方法的調用順序:
// 首先會調用awakeFromNib,在里面設置屏幕的刷新率,然后在顯示view的時候調用了drawRect:(CGRect)rect方法,添加了一張雪花的圖片,然后屏幕在刷新的時候調用了update 的方法,每一次調用的時候都會進行重繪,重繪時又調用drawRect:(CGRect)rect 方法更新圖片的y 位置
- (void)drawRect:(CGRect)rect {
//加載圖片
UIImage *image = [UIImage imageNamed:@"雪花"];
[image drawAtPoint:CGPointMake(0, _snowY)];
}
圖片加水印
- 不僅圖片可以繪畫到圖形上下文中,NSString字符串也可以
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
//生成一張圖片
//0.加載圖片
UIImage *oriImage = [UIImage imageNamed:@"小黃人"];
//1.創建位圖上下文(size:開啟多大的上下文,就會生成多大的圖片)
UIGraphicsBeginImageContext(oriImage.size);
//2.把圖片繪制到上下文當中
[oriImage drawAtPoint:CGPointZero]; // CGPointZero 在沒有完全確定位置的時候用CGPointZero代替
//3.繪制水印
NSString *str = @"小黃人";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSFontAttributeName] = [UIFont systemFontOfSize:20];
dict[NSForegroundColorAttributeName] = [UIColor redColor];
[str drawAtPoint:CGPointZero withAttributes:dict];
//4.從上下文當中生成一張圖片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.關閉位圖上下文
UIGraphicsEndImageContext();
self.imageV.image = newImage;
}
利用貝曲爾曲線和圖形上下文裁剪圖片
- (void)viewDidLoad {
[super viewDidLoad];
//生成一張圓形圖片
//0.加載圖片
UIImage *oriImage = [UIImage imageNamed:@"阿貍頭像"];
//1.開啟一個和圖片一樣大小的位圖上下文
UIGraphicsBeginImageContext(oriImage.size);
//2.設置一個裁剪區域(圓形),從左上角開始,
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, oriImage.size.width, oriImage.size.height)];
//把路徑設置成裁剪區域(超過裁剪區域以外的內容會自動被裁剪掉)
[path addClip];
//3.把圖片繪制到上下文當中
[oriImage drawAtPoint:CGPointZero];
//4.從上下文當中生成一張圖片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.關閉上下文
UIGraphicsEndImageContext();
self.imageV.image = newImage;
}
圖片截屏
- (IBAction)pan:(UIPanGestureRecognizer *)pan {
//獲取當前手指所在的點
CGPoint curP = [pan locationInView:self.imageV];
//判斷手勢的狀態
if(pan.state == UIGestureRecognizerStateBegan) {
//記錄當前手指的開始點
self.startP = curP;
} else if(pan.state == UIGestureRecognizerStateChanged) {
//rect
CGFloat w = curP.x - self.startP.x;
CGFloat h = curP.y - self.startP.y;
CGRect rect = CGRectMake(self.startP.x, self.startP.y, w, h);
self.coverView.frame = rect;
}else if(pan.state == UIGestureRecognizerStateEnded) {
//生成一張圖片
UIGraphicsBeginImageContext(self.imageV.bounds.size);
//設置裁剪區域
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.coverView.frame];
[path addClip];
//2.把UIImageV當中的內容渲染到上下文當中
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.imageV.layer renderInContext:ctx];
//從上下文當中獲取圖片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//關閉上下文
UIGraphicsEndImageContext();
self.imageV.image = newImage;
[self.coverView removeFromSuperview];
}
}