简介
UIBezierPath类创建基于矢量的路径,例如椭圆大概矩形,大概有多个直线和曲线段构成的外形。
UIBezierPath是UIKit中的一个关于图形绘制的类,是通过Quartz 2D也就是CG(Core Graphics)CGPathRef的封装得到的,从高级特性支持来看不及CG。
利用UIBezierPath,你只能在当前图形上下文中绘制。 CGContextRef即图形上下文。
1.重写UIView的drawRect方法,在该方法里便可得到context;
2.调用UIGraphicsBeginImageContextWithOptions方法得到
drawRect: 触发触发机遇
1、当view第一次表现到屏幕上时;
2、当调用view的setNeedsDisplay大概setNeedsDisplayInRect:方法时。
绘制流程
- 初始化一个 UIBezierPath 对象
- 设置相关的属性;
- 调用 -moveToPoint: 方法初始线段的出发点;
- 添加线段大概曲线段去构建一个大概多个子路径;
- (void)drawRectCGRect)rect // 重写drawRect方法{ // 1.初始化图形相应的UIBezierPath对象 UIBezierPath* aPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 200)]; // 2. // 2.设置一些修饰属性 aPath.lineWidth = 8.0; //路径的尽头外形, aPath.lineCapStyle = kCGLineCapRound; //路径的毗连点外形 aPath.lineJoinStyle = kCGLineCapRound; UIColor *color = [UIColor colorWithRed:0 green:0 blue:0.7 alpha:1]; [color set]; // 3.出发点 [aPath moveToPoint:CGPointMake(20, 20)]; // 4.绘制线条 [aPath addLineToPoint:CGPointMake(100, 100)]; [aPath stroke]; // 渲染,完成绘制}创建 UIBezierPath
- 创建而且返回一个新的 UIBezierPath 对象
+ (instancetype) bezierPath;
- 通过一个矩形, 创建而且返回一个新的 UIBezierPath 对象
/** * 该方法将会创建一个闭合路径, 起始点是 rect 参数的的 origin, 而且按照顺时针方向添加直线, 终极形成矩形 * @param rect: 矩形路径的 Frame */+ (instancetype)bezierPathWithRectCGRect)rect;
- 通过一个指定的矩形中的椭圆形, 创建而且返回一个新的 UIBezierPath 对象
/** * 该方法将会创建一个闭合路径, 该方法会通过顺时针的绘制贝塞尔曲线, 绘制出一个近似椭圆的外形. 如果 rect 参数指定了一个矩形, 那么该 UIBezierPath 对象将会形貌一个圆形. * @param rect: 矩形路径的 Frame */+ (instancetype)bezierPathWithOvalInRectCGRect)rect;
- 根据一个圆角矩形, 创建而且返回一个新的 UIBezierPath 对象
/** * 该方法将会创建一个闭合路径, 该方法会顺时针方向一连绘制直线和曲线. 当 rect 为正方形时且 cornerRadius 便是边长一半时, 则该方法会形貌一个圆形路径. * @param rect: 矩形路径的 Frame * @param cornerRadius: 矩形的圆角半径 */+ (instancetype) bezierPathWithRoundedRectCGRect)rect cornerRadiusCGFloat)cornerRadius;
- 根据一个圆角矩形, 创建而且返回一个新的 UIBezierPath 对象
/** * 该方法将会创建一个闭合路径, 该方法会顺时针方向一连绘制直线和曲线. * @param rect: 矩形路径的 Frame * @param corners: UIRectCorner 枚举范例, 指定矩形的哪个角变为圆角 * @param cornerRadii: 矩形的圆角半径 */+ (instancetype) bezierPathWithRoundedRectCGRect)rect byRoundingCornersUIRectCorner)corners cornerRadiiCGSize)cornerRadii;
- 通过一个圆弧, 创建而且返回一个新的 UIBezierPath 对象
/** * 该方法会创建出一个开放路径, 创建出来的圆弧是圆的一部门. 在默认的坐标体系中, 开始角度 和 竣事角度 都是基于单元圆的(看下面这张图). 调用这个方法之后, currentPoint 将会设置为圆弧的竣事点. * 举例来说: 指定实在角度为0, 指定竣事角度为π, 设置 clockwise 属性为 YES, 将会绘制出圆的下半部门. * 然而当我们不修改起始角度 和 竣事角度, 我们仅仅将 clockwise 角度设置为 NO, 则会绘制出来一个圆的上半部门. * @param center: 圆心 * @param radius: 半径 * @param startAngle: 起始角度 * @param endAngle: 竣事角度 * @param clockwise: 是否顺时针绘制 */+ (instancetype) bezierPathWithArcCenterCGPoint)center radiusCGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
- 通过一个 CGPath, 创建而且返回一个新的 UIBezierPath 对象
+ (instancetype) bezierPathWithCGPath:(CGPathRef)CGPath;
- 创建并返回一个新的BezierPath, 这个 BezierPath 的方向是原 BezierPath 的反方向
/** * 通过该方法反转一条路径, 并不会修改该路径的样子. 它仅仅是修改了绘制的方向 * @return: 返回一个新的 UIBezierPath 对象, 外形和原来路径的外形一样, * 但是绘制的方向相反. */- (UIBezierPath *) bezierPathByReversingPath;构造路径
- 将 UIBezierPath 对象的 currentPoint 移动到指定的点
/** * 如果当前有正在绘制的子路径, 该方法则会隐式的竣事当前路径, * 并将 currentPoint 设置为指定点. 当上一条子路径被克制, 该方法 * 实际上并不会去闭合上一条子路径. 以是上一条自路径的起始点 和 * 竣事点并没有被链接. * 对于大多数构造路径相关的方法而言, 在你绘制直线或曲线之前, 须要先调用这个方法. * @param point: 当前坐标体系中的某一点 */- (void)moveToPoint:(CGPoint)point;
/** * 该方法将会从 currentPoint 到 指定点 链接一条直线. * Note: 在追加完这条直线后, 该方法将会更新 currentPoint 为 指定点 * 调用该方法之前, 你必须先设置 currentPoint. 如果当前绘制路径 * 为空, 而且未设置 currentPoint, 那么调用该方法将不会产生任何 * 结果. * @param point: 绘制直线的尽头坐标, 当前坐标体系中的某一点 */- (void)addLineToPoint:(CGPoint)point;
/** * 该方法将会从 currentPoint 添加一条指定的圆弧. * 该方法的先容和构造方法中的一样. 请前去上文检察 * @param center: 圆心 * @param radius: 半径 * @param startAngle: 起始角度 * @param endAngle: 竣事角度 * @param clockwise: 是否顺时针绘制 */- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0);
/** * 该方法将会从 currentPoint 到 指定的 endPoint 追加一条二次贝塞尔曲线. * currentPoint、endPoint、controlPoint 三者的关系终极界说了二次贝塞尔曲线的外形. * 二次贝塞尔曲线的弯曲由一个控制点来控制. 如下图所示 * Note: 调用该方法前, 你必须先设置 currentPoint, 如果路径为空, * 而且尚未设置 currentPoint, 调用该方法则不会产生任何结果. * 当添加完贝塞尔曲线后, 该方法将会自动更新 currentPoint 为 * 指定的竣事点 * @param endPoint: 尽头 * @param controlPoint: 控制点 */- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;
/** * 该方法将会从 currentPoint 到 指定的 endPoint 追加一条三次贝塞尔曲线. * 三次贝塞尔曲线的弯曲由两个控制点来控制. 如下图所示 * Note: 调用该方法前, 你必须先设置 currentPoint, 如果路径为空, * 而且尚未设置 currentPoint, 调用该方法则不会产生任何结果. * 当添加完贝塞尔曲线后, 该方法将会自动更新 currentPoint 为 * 指定的竣事点 * @param endPoint: 尽头 * @param controlPoint1: 控制点1 * @param controlPoint2: 控制点2 */- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;
/** * 该方法将会从 currentPoint 到子路经的出发点 绘制一条直线, * 以此来关闭当前的自路径. 紧接着该方法将会更新 currentPoint * 为 刚添加的这条直线的尽头, 也就是当前子路经的出发点. */- (void)closePath;
- 删除 UIBezierPath 对象中的全部点, 结果也就等同于删除了全部子路经
- (void)removeAllPoints;
- 将指定 UIBezierPath 中的内容添加到当前 UIBezierPath 对象中
/** * 该方法将会在当前 UIBezierPath 对象的路径中追加 * 指定的 UIBezierPath 对象中的内容. */- (void)appendPath:(UIBezierPath *)bezierPath;
- UIBezierPath 中的 CGPath 对象
/** * 获取这个属性, 你将会得到一个不可变的 CGPathRef 对象, * 他可以传入 CoreGraphics 提供的函数中 * 你可以是用 CoreGraphics 框架提供的方法创建一个路径, * 并给这个属性赋值, 当时设置了一个新的路径后, * 这个将会对你给出的路径对象举行 Copy 操纵 */@property(nonatomic) CGPathRef CGPath;
/** * 该属性的值, 将会是下一条绘制的直线或曲线的起始点. * 如果当前路径为空, 那么该属性的值将会是 CGPointZero */@property(nonatomic, readonly) CGPoint currentPoint;绘图属性
/** * 线宽属性界说了 `UIBezierPath` 对象中绘制的曲线规格. 默以为: 1.0 */@property(nonatomic) CGFloat lineWidth;
/** * 该属性应用于曲线的尽头和出发点. 该属性在一个闭合子路经中是无结果的. 默以为: kCGLineCapButt */@property(nonatomic) CGLineCap lineCapStyle;// CGPath.h/* Line cap styles. */typedef CF_ENUM(int32_t, CGLineCap) { kCGLineCapButt, kCGLineCapRound, kCGLineCapSquare};
/** * 默以为: kCGLineJoinMiter. */@property(nonatomic) CGLineJoin lineJoinStyle;// CGPath.h/* Line join styles. */typedef CF_ENUM(int32_t, CGLineJoin) { kCGLineJoinMiter, kCGLineJoinRound, kCGLineJoinBevel};
/** * 两条线交汇处内角和外角之间的最大间隔, 只有当毗连点样式为 kCGLineJoinMiter * 时才访问效,最大限定为10 * 我们都知道, 两条直线相交时, 夹角越小, 斜接长度就越大. * 该属性就是用来控制最大斜接长度的. * 当我们设置了该属性, 如果斜接长度高出我们设置的范围, * 则毗连处将会以 kCGLineJoinBevel 毗连范例举行表现. */@property(nonatomic) CGFloat miterLimit;
/** * 该属性用来确定渲染曲线路径的准确度. * 该属性的值用来丈量真实曲线的点和渲染曲线的点的最大答应间隔. * 值越小, 渲染精度越高, 会产生相对更平滑的曲线, 但是须要泯灭更 * 多的盘算时间. 值越大导致则会低沉渲染精度, 这会使得渲染的更迅 * 速. flatness 的默认值为 0.6. * Note: 大多数情况下, 我们都不须要修改这个属性的值. 然而当我们 * 渴望以最小的斲丧去绘制一个临时的曲线时, 我们大概会临时增 * 大这个值, 来得到更快的渲染速率. */@property(nonatomic) CGFloat flatness;
/** * 设置为 YES, 则路径将会利用 基偶规则 (even-odd) 举行添补. * 设置为 NO, 则路径将会利用 非零规则 (non-zero) 规则举行添补. */@property(nonatomic) BOOL usesEvenOddFillRule;
/** * @param pattern: 该属性是一个 C 语言的数组, 此中每一个元素都是 CGFloat * 数组中的元素代表着线段每一部门的长度, 第一个元素代表线段的第一条线, * 第二个元素代表线段中的第一个间隙. 这个数组中的值是轮番的. 来表明一下 * 什么叫轮番的. * 举个例子: 声明一个数组 CGFloat dash[] = @{3.0, 1.0}; * 这意味着绘制的虚线的第一部门长度为3.0, 第一个间隙长度为1.0, 虚线的 * 第二部门长度为3.0, 第二个间隙长度为1.0\. 以此类推. * @param count: 这个参数是 pattern 数组的个数 * @param phase: 这个参数代表着, 虚线从哪里开始绘制. * 举个例子: 这是 phase 为 6\. pattern[] = @{5, 2, 3, 2}; 那么虚线将会 * 第一个间隙的中央部门开始绘制, 如果不是很明确就请继续往下看, * 下文实战部门会对虚线举行解说. */- (void)setLineDash:(const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase;
/** * 该方法可以重新获取之前设置过的虚线样式. * Note: pattern 这个参数的容量必须大于该方法返回数组的容量. * 如果无法确定命组的容量, 那么可以调用两次该方法, 第一次 * 调用该方法的时间, 传入 count 参数, 然后在用 count 参数 * 来申请 pattern 数组的内存空间. 然后再第二次正常的调用该方法 */- (void)getLineDash:(CGFloat *)pattern count:(NSInteger *)count phase:(CGFloat *)phase;绘制路径
/** * 该方法当前的添补颜色 和 绘图属性对路径的封闭地区举行添补. * 如果当前路径是一条开放路径, 该方法将会隐式的将路径举行关闭后举行添补 * 该方法在举行添补操纵之前, 会自动生存当前绘图的状态, 以是我们不须要 * 本技艺动的去生存绘图状态了. */- (void)fill;
/** * 该方法当前的添补颜色 和 绘图属性 (外加指定的肴杂模式 和 透明度) * 对路径的封闭地区举行添补. 如果当前路径是一条开放路径, 该方法将 * 会隐式的将路径举行关闭后举行添补 * 该方法在举行添补操纵之前, 会自动生存当前绘图的状态, 以是我们不须要 * 本技艺动的去生存绘图状态了. * * @param blendMode: 肴杂模式决定了怎样和已经存在的被渲染过的内容举行合成 * @param alpha: 添补路径时的透明度 */- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
- (void)stroke;
/** * @param blendMode: 肴杂模式决定了怎样和已经存在的被渲染过的内容举行合成 * @param alpha: 添补路径时的透明度 */- (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;剪切路径
/** * 该方法将会修改当前绘图上下文的可视地区. * 当调用这个方法之后, 会导致接下来全部的渲染 * 操纵, 只会在剪切下来的地区内举行, 地区外的 * 内容将不会被渲染. * 如果你渴望实行接下来的绘图时, 删除剪切地区, * 那么你必须在调用该方法前, 先利用 CGContextSaveGState 方法 * 生存当前的绘图状态, 当你不再须要这个剪切地区 * 的时间, 你只须要利用 CGContextRestoreGState 方法 * 来规复之前生存的绘图状态就可以了. * @param blendMode: 肴杂模式决定了怎样和 * 已经存在的被渲染过的内容举行合成 * @param alpha: 添补路径时的透明度 */- (void)addClip;Hit Detection
/** * 该方法返回一个布尔值, 当曲线的覆盖地区包罗 * 指定的点(内部点), 则返回 YES, 否则返回 NO. * Note: 如果当前的路径是一个开放的路径, 那么 * 就算指定点在路径覆盖范围内, 该方法仍旧会 * 返回 NO, 以是如果你想判定一个点是否在一个 * 开放路径的范围内时, 你须要先Copy一份路径, * 并调用 -(void)closePath; 将路径封闭, 然后 * 再调用此方法来判定指定点是否是内部点. * @param point: 指定点. */- (BOOL) containsPoint:(CGPoint)point;
/** * 检测当前路径是否绘制过直线或曲线. * Note: 记着, 就算你仅仅调用了 moveToPoint 方法 * 那么当前路径也被看做不为空. */@property (readonly, getter=isEmpty) BOOL empty;
/** * 该属性形貌的是一个可以或许完全包罗路径中全部点 * 的一个最小的矩形地区. 该地区包罗二次贝塞尔 * 曲线和三次贝塞尔曲线的控制点. */@property (nonatomic, readonly) CGRect bounds;Apply Transform
/** * 该方法将会直接对路径中的全部点举行指定的放射 * 变更操纵. */- (void)applyTransform:(CGAffineTransform)transform;实例
Demo: https://github.com/iOSlixiang/Animations.git |