UIBezierPath主要用來繪制矢量圖形,它是基于Core Graphics對CGPathRef數(shù)據(jù)類型和path繪圖屬性的一個封裝焚鲜。使用UIBezierPath可以定義簡單的形狀垦页。
1雀费、UIBezierPath的屬性
1. CGPath:將UIBezierPath類轉(zhuǎn)換成CGPath,類似于UIColor的CGColor
2. currentPoint:當(dāng)前path的位置痊焊,可以理解為path的終點
3. lineWidth:path寬度
4. lineCapStyle:path端點樣式枚舉盏袄,有3種樣式
kCGLineCapButt, // 無端點
kCGLineCapRound, // 圓形端點
kCGLineCapSquare // 方形端點(樣式上和kCGLineCapButt是一樣的忿峻,但是比kCGLineCapButt長一點)
5. lineJoinStyle:拐角樣式枚舉,有3種樣式
kCGLineJoinMiter, // 尖角
kCGLineJoinRound, // 圓角
kCGLineJoinBevel // 缺角
6.miterLimit:最大斜接長度(只有在使用kCGLineJoinMiter是才有效)辕羽,邊角的角度越小逛尚,斜接長度就會越大
為了避免斜接長度過長,使用lineLimit屬性限制
如果斜接長度超過miterLimit刁愿,邊角就會以KCALineJoinBevel類型來顯示
2绰寞、UIBezierPath與Quartz2D
即UIBezierPath在drawRect中的使用,在實際中铣口,我們多使用UIBezierPath來自定義視圖滤钱。
矩形
- (void)drawRect:(CGRect)rect {
CGFloat lineWidth = 3;
//矩形(第一種方式)
UIBezierPath *rectPath = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, 50,50 )];
rectPath.lineWidth = lineWidth*2;
rectPath.lineCapStyle = kCGLineCapRound;
rectPath.lineJoinStyle = kCGLineJoinRound;
//閉合路徑
[rectPath closePath];
[[UIColor greenColor] set];
//繪制邊緣
[rectPath stroke];
//矩形(第二種方式)
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIBezierPath *pathRect = [UIBezierPath bezierPathWithRect:CGRectMake(70, 10, 50,50 )];
CGContextAddPath(ctx, pathRect.CGPath);
[[UIColor purpleColor] set];
CGContextFillPath(ctx);
}
圓/弧
- (void)drawRect:(CGRect)rect {
CGFloat lineWidth = 3;
CGContextRef ctx = UIGraphicsGetCurrentContext();
//矩形圓
UIBezierPath *roundPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(130, 10, 50, 50) cornerRadius:10];
CGContextAddPath(ctx, roundPath.CGPath);
CGContextSetLineWidth(ctx, lineWidth);
[[UIColor orangeColor] set];
CGContextStrokePath(ctx);
//實心圓
UIBezierPath *arcPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(35, 95) radius:25 startAngle:0 endAngle:M_PI*2 clockwise:NO];
[arcPath addLineToPoint:CGPointMake(35, 95)];
[arcPath closePath];
[[UIColor brownColor] set];
[arcPath fill];
CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 1);
//空心圓
/*
* clockwise 1為順時針 0為逆時針
* 順時針的理解:指定1創(chuàng)建順時針弧或0創(chuàng)建逆時針弧(startAngle為0時為逆時針弧脑题,非0為順時針患住)
*/
UIBezierPath *arcKPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(155, 95) radius:25 startAngle:M_PI_2 endAngle:M_PI clockwise:NO];
CGContextAddPath(ctx, arcKPath.CGPath);
CGContextSetLineWidth(ctx, lineWidth);
[[UIColor lightGrayColor] set];
CGContextStrokePath(ctx);
float angle = 0;
CGPoint center = CGPointMake(150, 160);
for (int index = 1; index < 5; index++) {
CGFloat startAngle = angle;
CGFloat endAngle = index*M_PI_2;
//實心圓
UIBezierPath *arcPath = [UIBezierPath bezierPathWithArcCenter:center radius:30 startAngle:startAngle endAngle:endAngle clockwise:YES];
[arcPath addLineToPoint:center];
[arcPath closePath];
[[self randColor] set];
[arcPath fill];
angle = endAngle;
}
}
- (UIColor *)randColor
{
//rand(),就返回一個類型為int的整數(shù),其范圍是0到RAND_MAX
float red = rand() / (float)RAND_MAX;
float green = rand() / (float)RAND_MAX;
float blue = rand() / (float)RAND_MAX;
return [UIColor colorWithRed:red green:green blue:blue alpha:1];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self setNeedsDisplay];
}
線條
- (void)drawRect:(CGRect)rect {
CGFloat lineWidth = 3;
CGContextRef ctx = UIGraphicsGetCurrentContext();
//線條
UIBezierPath *linePath = [UIBezierPath bezierPath];
[linePath moveToPoint:CGPointMake(10, 130)];
[linePath addLineToPoint:CGPointMake(60, 190)];
[linePath moveToPoint:CGPointMake(60, 130)];
[linePath addLineToPoint:CGPointMake(10, 190)];
CGContextAddPath(ctx, linePath.CGPath);
CGContextSetLineWidth(ctx, lineWidth*3);
CGContextSetLineCap(ctx, kCGLineCapSquare);
CGContextSetLineJoin(ctx, kCGLineJoinBevel);
[[UIColor blackColor] set];
CGContextStrokePath(ctx);
}
效果
曲線
- (void)drawRect:(CGRect)rect {
//1.獲取跟View相關(guān)聯(lián)的上下文.】
CGContextRef ctx = UIGraphicsGetCurrentContext();
//2.描述路徑
UIBezierPath *path = [UIBezierPath bezierPath];
//畫曲線,設(shè)置起點.還有一個控制點(用來控制曲線的方向跟彎曲程度)
//設(shè)置起點
//A: CGPointMake(10, 150)
[path moveToPoint:CGPointMake(10, 150)];
//添加一要曲線到某個點
//C:CGPointMake(200, 150) B:CGPointMake(150, 10)
[path addQuadCurveToPoint:CGPointMake(200, 150) controlPoint:CGPointMake(150, 10)];
//3.把路徑添加到上下文當(dāng)中
CGContextAddPath(ctx, path.CGPath);
//4.把上下文的內(nèi)容渲染View上
CGContextStrokePath(ctx);
}
2旭蠕、UIBezierPath與CAShapeLayer
UIBezierPath與CAShapeLayer的結(jié)合停团,是我們開發(fā)中最常見的,功能很強(qiáng)大掏熬。
CAShapeLayer與UIBezierPath的關(guān)系:
CAShapeLayer中shape代表形狀的意思佑稠,所以需要形狀才能生效
貝塞爾曲線可以創(chuàng)建基于矢量的路徑,而UIBezierPath類是對CGPathRef的封裝
貝塞爾曲線給CAShapeLayer提供路徑旗芬,CAShapeLayer在提供的路徑中進(jìn)行渲染舌胶。路徑會閉環(huán),所以繪制出了Shape
用于CAShapeLayer的貝塞爾曲線作為path疮丛,其path是一個首尾相接的閉環(huán)的曲線幔嫂,即使該貝塞爾曲線不是一個閉環(huán)的曲線
例如設(shè)置圓角:
- (void)setFillet
{
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = [UIImage imageNamed:@"test"];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:imageView.bounds.size];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
//設(shè)置大小
maskLayer.frame = imageView.bounds;
//設(shè)置圖形樣子
maskLayer.path = maskPath.CGPath;
imageView.layer.mask = maskLayer;
}
自定義視圖
- (void)addCustomizeView
{
CGFloat H = self.view.frame.size.height;
CGFloat W = self.view.frame.size.width;
CGFloat layerHeight = self.view.frame.size.height * 0.1;
UIBezierPath *bezier = [UIBezierPath bezierPath];
[bezier moveToPoint:CGPointMake(0, H-layerHeight)];
[bezier addLineToPoint:(CGPointMake(0, H - 1))];
[bezier addLineToPoint:(CGPointMake(W, H - 1))];
[bezier addLineToPoint:CGPointMake(W, H-layerHeight)];
[bezier addQuadCurveToPoint:CGPointMake(0, H-layerHeight) controlPoint:CGPointMake(W/2, H-layerHeight-40)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.lineWidth = 3;
shapeLayer.path = bezier.CGPath;
shapeLayer.fillColor = [UIColor grayColor].CGColor;
shapeLayer.strokeColor = [UIColor greenColor].CGColor;
[self.view.layer addSublayer:shapeLayer];
}
效果