CAShapeLayer 繼承與CALayer( 主要用於設置圖層的形狀)
CAShapeLayer對象屬性列表
屬性名 | 描述 |
---|---|
path | CGPathRef 對象,圖形邊線路徑 |
lineWidth | 邊線的寬度 |
strokeColor | 邊線的顏色 |
lineDashPattern | 設置邊線的樣式,默認為實線,該數組為一個NSNumber數組,數組中的數值依次表示虛線中,單個線的長度,和空白的長度,如:數組@[2,2,3,4] 表示 有長度為2的線,長度為2的空白,長度為3的線,長度為4的空白 不斷循環后組成的虛線。如圖:![]() |
lineDashPhase | 邊線樣式的起始位置,即,如果lineDashPattern設置為@[2,2,3,4],lineDashPhase即為第一個長度為2的線的起始位置 |
lineCap | 線終點的樣式,默認 kCALineCapButt ![]() ![]() ![]() |
lineJoin | 線拐點處的樣式,默認 kCALineJoinMiter ![]() ![]() ![]() |
strokeStart strokeEnd | CGFloat類型,[0,1] 表示畫邊線的起點和終點(即在路徑上的百分比) |
fillColor | CGColorRef對象,圖形填充色,默認為黑色 |
結合UIBezierPath 與 CAShapeLayer 畫圖
將UIBezierPath 對象 轉化為CGPathRef 對象, 賦值給CAShapeLayer的path屬性即可,即可畫出各種線條和圖形
layer.path = bezierPath.CGPath;
畫折線
- 畫折線的UIBezierPath相關方法
+ (instancetype)bezierPath
生成一個UIBezierPath對象, 多用於畫 不規則曲線 或 多邊圖形
- (void)moveToPoint:(CGPoint)point
添加路徑起點
- (void)addLineToPoint:(CGPoint)point
添加路徑起點外的其他點
在矩形中畫一條折線
- 效果圖
- 代碼
// 需要畫線的視圖
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame)- 100, 200, 200)];
lineView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:lineView];
// 線的路徑
UIBezierPath *linePath = [UIBezierPath bezierPath];
// 起點
[linePath moveToPoint:CGPointMake(20, 20)];
// 其他點
[linePath addLineToPoint:CGPointMake(160, 160)];
[linePath addLineToPoint:CGPointMake(180, 50)];
CAShapeLayer *lineLayer = [CAShapeLayer layer];
lineLayer.lineWidth = 2;
lineLayer.strokeColor = [UIColor greenColor].CGColor;
lineLayer.path = linePath.CGPath;
lineLayer.fillColor = nil; // 默認為blackColor
[lineView.layer addSublayer:lineLayer];
畫多邊形
- UIBezierPath相關方法
- (void)closePath
封閉曲線(連接曲線的起點和終點形成封閉曲線)
在矩形視圖中畫一個三角形
- 效果圖
- 代碼:
// 需要多邊形的視圖
UIView * polygonView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
polygonView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:polygonView];
// 線的路徑
UIBezierPath *polygonPath = [UIBezierPath bezierPath];
// 這些點的位置都是相對於所在視圖的
// 起點
[polygonPath moveToPoint:CGPointMake(20, 40)];
// 其他點
[polygonPath addLineToPoint:CGPointMake(160, 160)];
[polygonPath addLineToPoint:CGPointMake(140, 50)];
[polygonPath closePath]; // 添加一個結尾點和起點相同
CAShapeLayer *polygonLayer = [CAShapeLayer layer];
polygonLayer.lineWidth = 2;
polygonLayer.strokeColor = [UIColor greenColor].CGColor;
polygonLayer.path = polygonPath.CGPath;
polygonLayer.fillColor = nil; // 默認為blackColor
[polygonView.layer addSublayer:polygonLayer];
畫橢圓或圓
- 畫橢圓或圓的UIBezierPath相關方法
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect:
生成一個矩形的內切橢圓UIBezierPath對象,如果矩形是正方形,就為內切圓
在矩形中畫內切橢圓
- 效果圖
- 代碼
// 需要圓視圖
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 130, CGRectGetMidY(self.view.frame) - 100, 260, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 線的路徑
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:view.bounds];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.path = path.CGPath;
pathLayer.fillColor = nil; // 默認為blackColor
[view.layer addSublayer:pathLayer];
在矩形中畫內切圓,並把正方形切為圓
- 效果圖
- 代碼
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 線的路徑
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:view.bounds];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.path = path.CGPath;
// [view.layer addSublayer:pathLayer];
// pathLayer.fillColor = nil; // 默認為blackColor
view.layer.mask = pathLayer; // layer 的 mask屬性,添加蒙版
畫圓角矩形
- 畫圓角矩形的UIBezierPath相關方法
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
生成一個自定義圓角大小的矩形UIBezierPath對象
矩形添加圓角,切為圓角矩形
- 效果圖
- 代碼
// 需要畫圓角矩形
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 線的路徑
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:50];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.path = path.CGPath;
// pathLayer.fillColor = [UIColor lightGrayColor].CGColor; // 默認為blackColor
// [polygonView.layer addSublayer:polygonLayer];
view.layer.mask = pathLayer; // layer 的 mask屬性,添加蒙版
畫單角的圓角矩形的UIBezierPath相關方法
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii
為矩形的某一個角添加自定義大小的圓角(當自定義的圓角大小超過矩形寬或高的一半是,自動取矩形寬或高的一半作為圓角大小)
如果想對視圖單個角切圓角,和圓切圓角相同只需將UIBezierPath對象添加為mask即可。
給矩形左上角添加圓角:
- 效果圖
- 代碼
// 需要圓視圖
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 線的路徑
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(100, 0)];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.fillColor = nil; // 默認為blackColor
pathLayer.path = path.CGPath;
[view.layer addSublayer:pathLayer];
畫圓弧
- 畫圓弧的UIBezierPath相關方法
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
center:圓弧的中心,相對所在視圖; radius:圓弧半徑; startAngle:起始點的角度(相對角度坐標系0); endAngle:結束點的角度(相對角度坐標系0); clockwise:是否為順時針方向。
- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
在原有的線上添加一條弧線 。center:圓弧的中心,相對所在視圖; radius:圓弧半徑; startAngle:起始點的角度(相對角度坐標系0); endAngle:結束點的角度(相對角度坐標系0); clockwise:是否為順時針方向。
在矩形中畫一條圓弧
- 效果圖
- 代碼
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 線的路徑
CGPoint viewCenter = CGPointMake(view.frame.size.width / 2.0, view.frame.size.height / 2.0); // 畫弧的中心點,相對於view
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:viewCenter radius:50.0 startAngle:0 endAngle:M_PI_2 clockwise:YES];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.fillColor = nil; // 默認為blackColor
pathLayer.path = path.CGPath;
[view.layer addSublayer:pathLayer];
折線和弧線構成的曲線
- 效果圖
- 代碼
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 線的路徑
CGPoint viewCenter = CGPointMake(view.frame.size.width / 2.0, view.frame.size.height / 2.0); // 畫弧的中心點,相對於view
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(100, 100)];
[path addArcWithCenter:viewCenter radius:50 startAngle:0 endAngle:M_PI clockwise:YES]; // 添加一條弧線
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.fillColor = nil; // 默認為blackColor
pathLayer.path = path.CGPath;
[view.layer addSublayer:pathLayer];
二次貝塞爾曲線
- 二次貝賽爾曲線相關方法
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint
貝塞爾二次曲線,起點用 moveToPoint方法給出;endPoint:貝賽爾曲線終點;controlPoint:控制點;曲線是由起點趨向控制點最后到達終點(不會經過控制點)的曲線。控制點決定曲線的起始方向,起點和終點的距離決定曲線趨向控制點的程度。
設置相同起點,相同控制點,終點不同時貝賽爾曲線比較(即,起點終點距離不同)
- 效果圖
- 代碼
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
// 綠色二次貝塞爾曲線
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:CGPointMake(0, 100)];
CGPoint end1Point = CGPointMake(200, 50);
[path1 addQuadCurveToPoint:end1Point controlPoint:CGPointMake(100, 200)]; // 二次貝塞爾曲線
CAShapeLayer *path1Layer = [CAShapeLayer layer];
path1Layer.lineWidth = 2;
path1Layer.strokeColor = [UIColor greenColor].CGColor;
path1Layer.fillColor = nil; // 默認為blackColor
path1Layer.path = path1.CGPath;
[view.layer addSublayer:path1Layer];
// 紅色二次貝塞爾曲線
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(0, 100)];
CGPoint end2Point = CGPointMake(100, 50);
[path2 addQuadCurveToPoint:end2Point controlPoint:CGPointMake(100, 200)]; // 二次貝塞爾曲線
CAShapeLayer *path2Layer = [CAShapeLayer layer];
path2Layer.lineWidth = 2;
path2Layer.strokeColor = [UIColor redColor].CGColor;
path2Layer.fillColor = nil; // 默認為blackColor
path2Layer.path = path2.CGPath;
[view.layer addSublayer:path2Layer];
總結:起點和終點的距離越小,趨向控制點結束越早,趨向終點開始越早,曲線弧度越大。
起點終點相同,控制點不同
- 效果圖
- 代碼
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
CGPoint startPoint = CGPointMake(0, 100);
CGPoint endPoint = CGPointMake(200, 50);
// 綠色二次貝塞爾曲線
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:startPoint];
[path1 addQuadCurveToPoint:endPoint controlPoint:CGPointMake(100, 200)]; // 二次貝塞爾曲線
CAShapeLayer *path1Layer = [CAShapeLayer layer];
path1Layer.lineWidth = 2;
path1Layer.strokeColor = [UIColor greenColor].CGColor;
path1Layer.fillColor = nil; // 默認為blackColor
path1Layer.path = path1.CGPath;
[view.layer addSublayer:path1Layer];
// 紅色二次貝塞爾曲線
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:startPoint];
[path2 addQuadCurveToPoint:endPoint controlPoint:CGPointMake(100, 150)]; // 二次貝塞爾曲線
CAShapeLayer *path2Layer = [CAShapeLayer layer];
path2Layer.lineWidth = 2;
path2Layer.strokeColor = [UIColor redColor].CGColor;
path2Layer.fillColor = nil; // 默認為blackColor
path2Layer.path = path2.CGPath;
[view.layer addSublayer:path2Layer];
總結:控制點與起點和終點所在直線偏移距離越大,曲線弧度越大。
三次貝塞爾曲線
- UIBezierPath相關方法
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
三次貝賽爾曲線,起點用 moveToPoint方法給出;endPoint:貝賽爾曲線終點;controlPoint1:控制點1;controlPoint2:控制點2;
曲線是由起點趨向控制點1,之后趨向控制點2,最后到達終點(不會經過控制點)的曲線。在起點和終點所在直線方向上,曲線在起點和控制點1之間,趨向控制點1;在控制點2和終點之間,趨向控制點2.控制點與起點和終點所在直線的偏移影響曲線的偏移程度
- 效果圖
- 代碼
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100, CGRectGetMidY(self.view.frame) - 100, 200, 200)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];
CGPoint startPoint = CGPointMake(0, 100);
CGPoint endPoint = CGPointMake(200, 100);
// 綠色二次貝塞爾曲線
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:startPoint];
[path addCurveToPoint:endPoint controlPoint1:CGPointMake(50, 75) controlPoint2:CGPointMake(150, 125)]; // 二次貝塞爾曲線
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.fillColor = nil; // 默認為blackColor
pathLayer.path = path.CGPath;
[view.layer addSublayer:pathLayer];