贝塞尔曲线作用
贝塞尔曲线路径可用来绘制自定义路径,圆,弧度,矩形,单独圆角矩形等
UIBerzierPath类介绍
初始化方法
/// MARK: - 初始化方法【常规路径】
/// 矩形
public convenience init(rect: CGRect)
/// 椭圆 形状依赖于矩形(比如当矩形为正方形的时候为圆形)
public convenience init(ovalIn rect: CGRect)
/// 圆角矩形 四遍圆角一致
public convenience init(roundedRect rect: CGRect, cornerRadius: CGFloat) // rounds all corners with the same horizontal and vertical radius
/// 圆角矩形 可以设置任意一个或者多个圆角【corners控制】 cornerRadii: CGSize 圆角宽高参考【详情键cornerRadii参数说明】
public convenience init(roundedRect rect: CGRect, byRoundingCorners corners: UIRectCorner, cornerRadii: CGSize)
/// 弧度路径 radius: 圆半径 startAngle:弧度 比如二分之π(1(CGFloat.pi)/2) clockwise: 是否顺手针
public convenience init(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)
/// 根据CGPath初始化
public convenience init(cgPath CGPath: CGPath)
矩形单独设置某个圆角(cornerRadii参数说明)
在进行单独某个圆角设置的时候,需要设置圆角参数,类型未CGSize , 说明圆角成度根据宽高共同决定,但是两个值得有效范围为0到两边中最小值得一半
效果图参考
路径绘制方法
// MARK: - 自定义路径绘制【通过点与点之间的绘制】
open func move(to point: CGPoint) // 开始绘制点时
open func addLine(to point: CGPoint) // 点与点之间用线连接
/// 三次方贝塞尔曲线
open func addCurve(to endPoint: CGPoint, controlPoint1: CGPoint, controlPoint2: CGPoint)
/// 二次贝塞尔曲线
open func addQuadCurve(to endPoint: CGPoint, controlPoint: CGPoint)
@available(iOS 4.0, *)
open func addArc(withCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)
open func close()
open func removeAllPoints()
/// 添加其他路径
open func append(_ bezierPath: UIBezierPath)
其他属性和方法
open var cgPath: CGPath // 对应的cgPath
/// 逆转路径 【路径外表一致,只是最后一个点为最开始的点】
@available(iOS 6.0, *)
open func reversing() -> UIBezierPath
// Transforming paths
open func apply(_ transform: CGAffineTransform)
// MARK: - 路径信息
open var isEmpty: Bool { get }
open var bounds: CGRect { get } // 路径包含的矩形
open var currentPoint: CGPoint { get }
open func contains(_ point: CGPoint) -> Bool
// MARK: - 绘制属性
/// 线条颜色宽度
open var lineWidth: CGFloat
/// 线条起点和终点处理【值枚举 butt:默认 round:圆角 square:方形】
open var lineCapStyle: CGLineCap
/// 线条拐角处理【值枚举 miter:斜切(默认值) round:圆角(圆滑) bevel:斜角】
open var lineJoinStyle: CGLineJoin
/// 斜切限制 仅仅在 lineJoinStyle is kCGLineJoinMiter 有效
open var miterLimit: CGFloat
/// 曲线平坦经度 越小越光滑但是渲染越慢
open var flatness: CGFloat // 默认值0.6
/// 是否使用奇偶绕线规则
open var usesEvenOddFillRule: Bool // Default is NO. When YES, the even-odd fill rule is used for drawing, clipping, and hit testing.
/// 设置虚线
open func setLineDash(_ pattern: UnsafePointer<CGFloat>?, count: Int, phase: CGFloat)
open func getLineDash(_ pattern: UnsafeMutablePointer<CGFloat>?, count: UnsafeMutablePointer<Int>?, phase: UnsafeMutablePointer<CGFloat>?)
// Path operations on the current graphics context
/// 设置路径环境 比如设置颜色红色填充 UIColor.red.setFill() 之后path.fill()即可设置路径颜色
open func fill()
/// 设置填充环境 比如设置颜色蓝色填充 UIColor.blue.setStroke() 之后path.strocke()即可设置路径颜色
open func stroke()
// These methods do not affect the blend mode or alpha of the current graphics context
/// 指定混合模式和透明度填充
open func fill(with blendMode: CGBlendMode, alpha: CGFloat)
/// 指定混合模式和透明度填充路径
open func stroke(with blendMode: CGBlendMode, alpha: CGFloat)
/// 与当前图形上下文的剪切路径相交于接收方路径所包围的区域,并使生成的形状为当前剪切路径[具体不太懂]
open func addClip()
弧度图解
二次贝塞尔曲线图解
三次贝赛尔曲线图解
路径虚线
let path = UIBezierPath(ovalIn: CGRect(x: 10, y: 40 , width: 100, height: 100))
UIColor.red.setStroke()
/// 虚线空白【是一个数组】
var dashConfig: [CGFloat] = [3.0,4.0]
// 注意参数形式使用的是地址 count 为虚线数组数量。 phase参数效果明白
path.setLineDash(&dashConfig, count:dashConfig.count , phase: 0)
path.stroke() // 这个一定要放在各种属性设置后面
使用 UIBezierPath 自定义虚线视图
重写 `drawRect` 方法
#import "DashLine.h"
@implementation DashLine
- (void)drawRect:(CGRect)rect {
[self.lineColor set]; //设置线条颜色
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = self.frame.size.height;
path.lineCapStyle = self.lineCap;
if (self.direction == DashLineDirectionHorizontal) {
[path moveToPoint:CGPointMake(0, self.frame.size.height/2)];
[path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height/2)];
} else {
[path moveToPoint:CGPointMake(self.frame.size.width/2, 0)];
[path addLineToPoint:CGPointMake(self.frame.size.width/2, self.frame.size.height)];
}
if (self.lineDash) {
CGFloat dash[self.lineDash.count]; // c 数组
for (int i=0; i<self.lineDash.count; i++) {
dash[i] = self.lineDash[i].doubleValue;
}
[path setLineDash:dash count:self.lineDash.count phase:self.lineDashPhase];
}
// 绘制
[path stroke];
}
@end
属性定义DashLine.h 文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, DashLineDirection) {
DashLineDirectionHorizontal = 0,
DashLineDirectionVertical = 1,
};
/**
水平虚线
```
DashLine *line = [[DashLine alloc] initWithFrame:CGRectMake(10, 100, 300, 4)];
line.lineCap = kCGLineCapButt;
line.lineDash = @[@5, @5];
line.lineColor = UIColor.redColor;
[self.view addSubview:line];
```
*/
@interface DashLine : UIView
/// 端点样式,默认为kCGLineCapButt
///
/// 如果为kCGLineCapRound,半圆角,则左右实线会增加半个高度的圆角,如果想要空白和实线等距,要等量给间隔增加差值。比如高度4,想要5个实线5个间隔。则应该设置 lineDash = @[@(1),@(9)];如下示例:
/// ```
/// DashLine *line = [[DashLine alloc] initWithFrame:CGRectMake(10, 100, 300, 4)];
/// line.lineCap = kCGLineCapRound;
/// line.lineDash = @[@1, @9];
/// ```
@property (nonatomic, assign) CGLineCap lineCap;
/// 第一个点绘制,偏移的像素
@property (nonatomic, assign) CGFloat lineDashPhase;
@property (nonatomic, strong)UIColor *lineColor;
/// lineDash =@[@10,@10],表示先绘制10个点,再跳过10个点,如此反复
@property (nonatomic, copy)NSArray<NSNumber *> *lineDash;
/// 虚线方向,默认水平方向
@property (nonatomic, assign) DashLineDirection direction;
@end
NS_ASSUME_NONNULL_END