IOS图形绘制路径 CGPATH & CGCONTEXT相关联的CGPath & UIBezierPath

CGPathCreateMutable //创建一个可变图形的路径 需要自己释放
CGPathCreateWithEllipseInRect //创建一个椭圆形的不可改变的路径
CGPathCreateWithRect //创建一个不变的矩形路径
CGPathCreateCopy //创建一个不可变的可以拷贝的路径
CGPathCreateCopyByDashingPath //创建一个虚线路径可以复制的
CGPathCreateCopyByStrokingPath //创建一个画的路径
CGPathCreateMutableCopy //创建一个现有的图形路径的副本
 //由一个转换矩阵变换一个图形路径创建一个不可变的副本
CGPathCreateCopyByTransformingPath
//创建一个由一个转换矩阵变换一个图形路径的可变副本
CGPathCreateMutableCopyByTransformingPath
 
CGPathRelease //递减保留的图形路径计数
CGPathRetain //增加保留的图形路径计数
 
CGPathAddArc 一个//弧形追加一个可变图形的路径, 可能由直线段之前
CGPathAddEllipseInRect //添加一个适合的椭圆在矩形的内部
CGPathEqualToPath //两个图形路径是否相等
CGPathGetBoundingBox //返回图形路径中包含所有点的包围盒
CGPathGetPathBoundingBox //返回图形路径的边界框
CGPathGetCurrentPoint //返回当前点的路径
CGPathGetTypeID //返回Quartz图形路径的核心基础类型的标识符
 
CGPathIsEmpty //指示路径是否为空
CGPathIsRect //图形路径指示是否代表一个矩形
CGPathContainsPoint //检查一个点是否在图形路径中

与CGContext关联的Path总结

点&线

  1. AddLineToPoint实现方式在线条alpha为1,即不透明的时候和AddLines一样,而且是实时画线。

  2. 但是当线条半透明的时候,AddLines在一条线自身重叠时不会透明度重叠。

  3. 而AddLineToPoint却会导致透明度重叠,且move touch的点出也会出现透明度重叠,会显示成点和点之间透明度正确,点上不透明的问题。

//获取上下文
CGContextRef context = UIGraphicsGetCurrentContext(); 

//点(在Context中移动画笔到(0,0)个点)
CGContextMoveToPoint(context, 0, 0);

//线(画笔从上一个点画到(1,1)这个点)
CGContextAddLineToPoint(context, 1, 1);

//添加点的坐标

CGPoint points[] = {
    CGPointMake(0, 0),
    CGPointMake(2, 2),
    CGPointMake(3, 3)
};

//求出poins长度
int count = sizeof(points)/sizeof(points[0]);

//画线 
CGContextAddLines(context, points, count);

/*注意 
AddLineToPoint实现方式在线条alpha为1,
即不透明的时候和AddLines一样,而且是实时画线。 
但是当线条半透明的时候,AddLines在一条线自身重叠时不会透明度重叠。 
而AddLineToPoint却会导致透明度重叠,且move touch的点出也会出现透明度重叠,
会显示成点和点之间透明度正确,点上不透明的问题。 
*/

曲线

//第一种
void CGContextAddArc(CGContextRef c,
                     CGFloat x, //圆心的x坐标
                     CGFloat y, //圆心的x坐标
                     CGFloat radius, //圆的半径
                     CGFloat startAngle, //开始弧度
                     CGFloat endAngle, //结束弧度
                     int clockwise //0表示顺时针,1表示逆时针
);
/*
 假如想创建一个完整的圆圈,那么 开始弧度就是0 结束弧度是 2pi,
 因为圆周长是 2pir. 最后,函数执行完后,current point就被重置为(x,y).
 还有一点要注意的是,假如当前path已经存在一个subpath,
 那么这个函数执行的另外一个效果是 会有一条直线,从current point到弧的起点
 */

//第二种
void CGContextAddArcToPoint(CGContextRef c, CGFloat x1, //端点1的x坐标
                            CGFloat y1, //端点1的y坐标
                            CGFloat x2, //端点2的x坐标
                            CGFloat y2, //端点2的y坐标
                            CGFloat radius //半径
);
/*
 原理:首先画两条线,这两条线分别是 current point to (x1,y1) 和(x1,y1) to (x2,y2).
 这样就是出现一个以(x1,y1)为顶点的两条射线, 然后定义半径长度,
 这个半径是垂直于两条射线的,这样就能决定一个圆了,更好的理解看下图,
 不过个人认为下图所标的 tangent point 1的位置是错误的。
 最后,函数执行完后,current point就被重置为(x2,y2).
 还有一点要注意的是,假如当前path已经存在一个subpath,
 那么这个函数执行的另外一个效果是 会有一条直线,从current point到(x1,y1)
 */

//传说中的不规则的曲线

// 画曲线,一般是一条直线,然后定义几个控制点,使直线变弯曲。 三次曲线函数
void CGContextAddCurveToPoint(CGContextRef c, CGFloat cp1x, //控制点1 x坐标
                              CGFloat cp1y, //控制点1 y坐标
                              CGFloat cp2x, //控制点2 x坐标
                              CGFloat cp2y, //控制点2 y坐标
                              CGFloat x, //直线的终点 x坐标
                              CGFloat y //直线的终点 y坐标
);

// 二次曲线函数
void CGContextAddQuadCurveToPoint(CGContextRef c, CGFloat cpx, //控制点 x坐标
                                  CGFloat cpy, //控制点 y坐标
                                  CGFloat x, //直线的终点 x坐标
                                  CGFloat y //直线的终点 y坐标
);

裁剪的方法:

CGConextClip; 
CGContextEOClip; 
CGContextClipToRect; 
CGContextClipToRects; 
CGContextClipToMask;

图像绘制

UIGraphicsBeginImageContextWithOptions 
UIGraphicsEndImageContext

PDF绘制

UIGraphicsBeginPDFContextToFile(ToData) 
UIGraphicsEndPDFContext

翻转屏幕变换:

CGContextTranslateCTM(graphicsContext, 0.0, drawingRect.size.height);
CGContextScaleCTM(graphicsContext, 1.0, -1.0);
 

CGPATH &CGCONTEXT相关联的CGPath中的对应关系

//创建一个路径 
CGPathCreateMutable = CGContextBeginPath
//画笔(路径)从哪里开始 
CGPathMoveToPoint = CGContextMoveToPoint
//添加一个点(线)
CGPathAddLineToPoint = CGContextAddLineToPoint 
//创建一个曲线 
CGPathAddCurveToPoint = CGContextAddCurveToPoint
//创建一个椭圆
CGPathAddEllipseInRect = CGContextAddEllipseInRect 
//创建一个圆形路径 
CGPathAddArc = CGContextAddArc
//创建一个矩形路径
CGPathAddRect = CGContextAddRect 
//闭合路径
CGPathCloseSubPath = CGContextCloseSubPath

UIBezierPath

好了看完了上面的各种函数是不是头都大了那么看看我们的UIBezierPath

属性


CGPath:将UIBezierPath类转换成CGPath,类似于UIColor的CGColor

empty:只读类型,路径上是否有有效的元素

bounds:和view的bounds是不一样的,它获取path的X坐标、Y坐标、宽度,但是高度为0

currentPoint:当前path的位置,可以理解为path的终点

lineWidth:path宽度

lineCapStyle:path端点样式,有3种样式   
kCGLineCapButt:无端点   
kCGLineCapRound:圆形端点   
kCGLineCapSquare:方形端点(样式上和kCGLineCapButt是一样的,但是比kCGLineCapButt长一点)

lineJoinStyle:拐角样式    
kCGLineJoinMiter:尖角   
kCGLineJoinRound:圆角   
kCGLineJoinBevel:缺角

miterLimit:最大斜接长度(只有在使用kCGLineJoinMiter是才有效), 
边角的角度越小,斜接长度就会越大 为了避免斜接长度过长,使用lineLimit属性限制,
如果斜接长度超过miterLimit,边角就会以KCALineJoinBevel类型来显示

flatness:弯曲路径的渲染精度,默认为0.6,越小精度越高,相应的更加消耗性能。

usesEvenOddFillRule:单双数圈规则是否用于绘制路径,默认是NO

UIRectCorner:角   
UIRectCornerTopLeft:左上角   
UIRectCornerTopRight:右上角   
UIRectCornerBottomLeft:左下角   
UIRectCornerBottomRight:右下角   
UIRectCornerAllCorners:所有四个角

UIBezierPath


1.创建UIBezierPath
//矩形路径(rect矩形的位置和大小) 
- (instancetype)bezierPathWithRect:(CGRect)rect:

//创建在rect里的内切曲线: (参数:rect-矩形的Frame) 
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect:

//创建带有圆角的矩形,当矩形变成正圆的时候,Radius就不再起作用: 
//rect:矩形的Frame cornerRadius:圆角大小)

- (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
//圆角的矩形(设定特定的角为) 
/* 
rect:矩形的Frame corners:指定的圆角      
cornerRadii:圆角的大小 */

- (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
//圆弧 
/* 
center->圆点 
radius->半径 
startAngle->起始位置
endAngle->结束为止 
clockwise->是否顺时针方向 */

- (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
//通过已有路径创建路径: 
//CGPath->已有路径
- (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath

一些对象方法

//移动到某一点:(point:目标位置) 
- (void)moveToPoint:(CGPoint)point; 
//绘制一条线:(point:目标位置)
- (void)addLineToPoint:(CGPoint)point; 
//闭合路径,即在终点和起点连一根线 
- (void)closePath;
//追加路径 
- (void)appendPath:(UIBezierPath *)bezierPath;
//扭转路径,即起点变成终点,终点变成起点 
- (UIBezierPath *)bezierPathByReversingPath;
//路径进行仿射变换
- (void)applyTransform:(CGAffineTransform)transform; 
//填充; 
- (void)fill; 
//描边,路径创建需要描边才能显示出来; 
- (void)stroke; 
//设置描边颜色,需要在设置后调用描边方法: 
- (void)setStroke;
//设置描边的混合模式
- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha; 
//设置描边的混合模式 
//blendMode->混合模式 alpha->透明度 
- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

//设置填充的混合模式: //blendMode:混合模式 alpha:透明度 
- (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

//修改当前图形上下文的绘图区域可见,随后的绘图操作导致呈现内容只有发生在指定路径的填充区域 
- (void)addClip;

/**
创建虚线
@param pattern C类型线性数据
@param count pattern中数据个数
@param phase 起始位置 
*/
- (void)setLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase;

//清空路径: 
- (void)removeAllPoints;

/**
创建三次贝塞尔曲线
@param endPoint 终点
@param controlPoint1 控制点1
@param controlPoint2 控制点2 
*/ 
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;

/**
创建二次贝塞尔曲线
@param endPoint 终点
@param controlPoint 控制点 
*/ 
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

/**

创建圆弧
@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;

你可能感兴趣的:(ios)