moveToPoint:
和addLineToPoint:
方法逐点构建的简单形状。moveToPoint:
方法设置你想要创建的形状的起点。从这一点开始,使用addLineToPoint:
方法创建形状的线条。您可以连续创建这些线,每条线都是在上一个点和您指定的新点之间形成的。- (void)drawRect:(CGRect)rect {
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:CGPointMake(100, 0)];
[bezierPath addLineToPoint:CGPointMake(200, 0)];
[bezierPath addLineToPoint:CGPointMake(300, 100)];
[bezierPath addLineToPoint:CGPointMake(150, 200)];
[bezierPath addLineToPoint:CGPointMake(0, 100)];
[bezierPath closePath];
}
UIBezierPath
类提供了使用弧段初始化新路径对象的支持。bezierPathWithArcCenter:radius:startAngle:endAngle:
顺时针:方法的参数定义了包含所需圆弧的圆以及圆弧本身的起点和终点。#define DEGREES_TO_RADIANS(degrees) ((pi * degrees)/ 180)
- (UIBezierPath *)createArcPath
{
UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150)
radius:75
startAngle:0
endAngle:DEGREES_TO_RADIANS(135)
clockwise:YES];
return aPath;
}
//弧是顺时针方向形成的。(逆时针方向画圆弧的虚线部分)
UIBezierPath类支持在路径中添加Quadratic curve
和Cubic curve
Bézier。曲线段从当前点开始,到指定的点结束。曲线的形状使用起点和终点与一个或多个控制点之间的切线定义。添加曲线:
Quadratic curve :addQuadCurveToPoint:controlPoint:
Cubic curve :addCurveToPoint:controlPoint1:controlPoint2:
椭圆和矩形是使用曲线和线段组合构建的常见路径类型。UIBezierPath
类包括bezierPathWithRect:
和bezierPathWithOvalInRect:
用于创建椭圆形或矩形路径的方便方法。这两个方法都创建一个新的路径对象,并用指定的形状初始化它。您可以立即使用返回的path
对象,也可以根据需要向其添加更多形状。
如果你想添加一个矩形到一个现有的路径对象中,你必须使用moveToPoint:
, addLineToPoint:
,和closePath
方法,就像你对任何其他多边形一样。在矩形的最后一侧使用closePath
方法可以方便地添加路径的最后一行,并标记矩形子路径的结束。
如果你想添加一个椭圆到一个现有的路径,最简单的方法是使用核心图形。虽然您可以使用addQuadCurveToPoint:controlPoint:
来近似椭圆曲面,但CGPathAddEllipseInRect
函数使用起来更简单,也更准确。有关详细信息,请参见核心图形函数修改路径
UIBezierPath
类实际上只是CGPathRef
数据类型和与该路径相关的绘图属性的包装器。虽然您通常使用UIBezierPath
类的方法添加直线段和曲线段,但该类还公开了一个CGPath
属性,您可以使用该属性直接修改底层路径数据类型。当您希望使用核心图形框架的功能构建路径时,可以使用此属性。
有两种方法来修改与UIBezierPath
对象相关的路径。你可以完全使用Core Graphics
函数来修改路径,或者你可以混合使用Core Graphics
函数和UIBezierPath
方法。在某些方面,完全使用Core Graphics
调用修改路径更容易。您可以创建一个可变的CGPathRef
数据类型,并调用您需要修改其路径信息的任何函数。完成后,将path
对象分配给相应的UIBezierPath
对象.
// Create the path data.
CGMutablePathRef cgPath = CGPathCreateMutable();
CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(0, 0, 300, 300));
CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(50, 50, 200, 200));
// Now create the UIBezierPath object.
UIBezierPath *aPath = [UIBezierPath bezierPath];
aPath.CGPath = cgPath;
aPath.usesEvenOddFillRule = YES;
// After assigning it to the UIBezierPath object, you can release
// your CGPathRef data type safely.
CGPathRelease(cgPath);
UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];
// Get the CGPathRef and create a mutable version.
CGPathRef cgPath = aPath.CGPath;
CGMutablePathRef mutablePath = CGPathCreateMutableCopy(cgPath);
// Modify the path and assign it back to the UIBezierPath object.
CGPathAddEllipseInRect(mutablePath, NULL, CGRectMake(50, 50, 200, 200));
aPath.CGPath = mutablePath;
// Release both the mutable copy of the path.
CGPathRelease(mutablePath);
创建UIBezierPath
对象后,你可以使用它的描边
和填充
方法在当前图形上下文中渲染它。不过,在你调用这些方法之前,通常还有一些其他任务要执行,以确保你的路径被正确绘制:
UIColor
类的方法设置所需的笔画
和填充
颜色。如果您创建了相对于点
(0,0)
的路径,则可以对当前绘图上下文应用适当的仿射转换。例如,要从点(10,10)
开始绘制形状,您将调用CGContextTranslateCTM
函数,并为水平和垂直平移值指定10
。调整图形上下文(而不是路径对象中的点)是首选,因为通过保存和恢复以前的图形状态,可以更容易地撤消更改。
UIBezierPath
实例的绘图属性在呈现路径时覆盖与图形上下文相关的值。- (void)drawRect:(CGRect)rect
{
// Create an oval shape to draw.
UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect:
CGRectMake(0, 0, 200, 100)];
// Set the render colors.
[[UIColor blackColor] setStroke];
[[UIColor redColor] setFill];
CGContextRef aRef = UIGraphicsGetCurrentContext();
// If you have content to draw after the shape,
// save the current state before changing the transform.
//CGContextSaveGState(aRef);
// Adjust the view's origin temporarily. The oval is
// now drawn relative to the new origin point.
CGContextTranslateCTM(aRef, 50, 50);
// Adjust the drawing options as needed.
aPath.lineWidth = 5;
// Fill the path before stroking it so that the fill
// color does not obscure the stroked line.
[aPath fill];
[aPath stroke];
// Restore the graphics state before drawing any other content.
//CGContextRestoreGState(aRef);
}
如上显示了一个drawRect:
方法的示例实现,该方法在自定义视图中绘制一个椭圆形。椭圆边界矩形的左上角位于视图坐标系中的点(50,50)
。因为填充操作直接绘制到路径边界,所以此方法在描边之前填充路径。这可以防止填充颜色遮住一半的描边线。
UIBezierPath
的containsPoint:
方法。此方法针对路径对象中的所有封闭子路径测试指定点,如果它位于其中任何子路径上或其中任何子路径内,则返回YES
。
containsPoint:
方法和Core Graphics
命中测试函数仅在封闭路径
上操作。对于打开的子路径,这些方法总是返回NO
。如果要对打开的子路径进行命中检测,必须创建路径对象的副本,并在测试点之前关闭
打开的子路径。
Core Graphics
。CGContextPathContainsPoint
函数允许您测试当前分配给图形上下文的路径的填充部分或描边部分上的点。- (BOOL)containsPoint:(CGPoint)point onPath:(UIBezierPath *)path inFillArea:(BOOL)inFill
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGPathRef cgPath = path.CGPath;
BOOL isHit = NO;
// Determine the drawing mode to use. Default to
// detecting hits on the stroked portion of the path.
CGPathDrawingMode mode = kCGPathStroke;
if (inFill)
{
// Look for hits in the fill area of the path instead.
if (path.usesEvenOddFillRule)
mode = kCGPathEOFill;
else
mode = kCGPathFill;
}
// Save the graphics state so that the path can be
// removed later.
CGContextSaveGState(context);
CGContextAddPath(context, cgPath);
// Do the hit detection.
isHit = CGContextPathContainsPoint(context, point, mode);
CGContextRestoreGState(context);
return isHit;
}
inFill
参数允许调用者指定是否应该根据路径的填充部分或描边部分测试该点。调用方传入的路径必须包含一个或多个封闭子路径,以便命中检测成功。绘制了个类似气泡的玩意
- (void)addQuadCurveToPoint:(CGPoint)endPoint
controlPoint:(CGPoint)controlPoint;
因为addQuadCurveToPoint
中是设置的endPoint
,所以上图中的弧点8
应是 3
的位置,弧点9
应是起点
位置
- (void)drawRect:(CGRect)rect
{
UIBezierPath *aPath = [UIBezierPath bezierPath];
[aPath moveToPoint:CGPointMake(50, 50)]; //起点
[aPath addLineToPoint:CGPointMake(150, 50)]; //2 弧线起点
[aPath addQuadCurveToPoint:CGPointMake(150, 100) controlPoint:CGPointMake(185, 75)]; //8圆点 10控制点 弧线
[aPath addLineToPoint:CGPointMake(100, 100)];//4 尖尖角起点
[aPath addLineToPoint:CGPointMake(85, 125)]; //5 尖尖角顶点
[aPath addLineToPoint:CGPointMake(70, 100)]; //6 尖尖角终点
[aPath addLineToPoint:CGPointMake(50, 100)]; //7 左边圆弧起点
[aPath addQuadCurveToPoint:CGPointMake(50, 50) controlPoint:CGPointMake(15, 75)]; // 9圆点 11控制点 圆弧
[aPath closePath]; // 闭合图形
aPath.lineJoinStyle = kCGLineJoinRound;
aPath.lineCapStyle = kCGLineCapRound;
[[UIColor yellowColor] setStroke];
[[UIColor purpleColor] setFill];
CGContextRef aref = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(aref, 50, 50);
aPath.lineWidth = 1;
[aPath fill];
[aPath stroke];
}