美文网首页iOS成长之路
Core Graphics 之 Paths (四)

Core Graphics 之 Paths (四)

作者: Niko_peng | 来源:发表于2018-08-27 12:40 被阅读0次

    Paths

    path定义了一个或多个形状或子路径。子路径可以由直线、曲线或两者组成。它可以是打开的路径可以是关闭的路径。子路可以是简单的形状,如直线、圆形、矩形或星形,也可以是更复杂的形状,如山脉的轮廓或抽象的涂鸦。图3-1显示了可以创建的一些路径。直线(在图的左上角)被虚线;线条也可以是实心的。弯弯曲曲的路径(在中间的顶部)由几条曲线组成,是一条开放的路径。同心圆被填满,但没有被填充。加州地图(在左下角)是一条封闭的路径,由许多曲线和线条组成,路径被绘制和填充。星形图展示了两种填充路径的选项,您将在本章后面读到。

    Figure 3-1 Quartz supports path-based drawing path_vector_examples.gif
    在本章中,您将了解组成路径的构建块,如何描边和绘制路径,以及影响路径外观的参数。

    路径创建和路径绘制

    路径创建和路径绘制是独立的任务。首先创建一条路径。当您想要呈现一个路径时,您需要请求Quartz来绘制它。如图3-1所示,您可以选择描边路径,填充路径,或者同时描边和填充。您还可以使用路径将其他对象的绘制限制在创建剪切区域的路径范围内。

    图3-2显示了已绘制的路径,其中包含两个子路径。左边的子路径是矩形,右边的子路径是由直线和曲线组成的抽象形状。图中每个子路径都被填充,它的轮廓被描边。
    Figure 3-2 A path that contains two shapes, or subpaths


    subpaths.gif

    图3-3显示了独立绘制的多条路径。每个路径都包含一个随机生成的曲线,其中一些曲线被填充,另一些则被绘制。绘图被一个裁剪区域限制在一个圆形区域。
    Figure 3-3 A clipping area constrains drawing


    circle_clipping.gif

    The Building Blocks

    子路径由直线、弧线和曲线构成。Quartz还提供了方便的函数,可以通过一个函数调用来添加矩形和椭圆。点也是路径的基本构建块,因为点定义了形状的起始和结束位置。

    Points

    点是在用户空间中指定位置的x和y坐标。您可以调用函数CGContextMoveToPoint来为新子路径指定起始位置。Quartz跟踪当前点,这是用于路径构建的最后一个位置。例如,如果您调用函数CGContextMoveToPoint来设置一个位置(10,10),那么将当前点移动到(10,10)。如果你画一条长50单位的水平线,这条线上的最后一点,也就是(60,10),变成了现在的点。线、弧和曲线总是从当前点开始画。

    大多数情况下,通过将两个浮点值传递给Quartz函数来指定一个点来指定x和y坐标。有些函数需要传递一个CGPoint数据结构,该结构包含两个浮点值。

    Lines

    直线由其端点定义。它的起点总是假设为当前点,所以当创建一行时,只指定它的端点。使用CGContextAddLineToPoint函数向子路径追加一行代码。

    通过调用CGContextAddLines函数,可以将一系列连接的行添加到路径中。你给这个函数传递一个点数组。第一个点必须是第一行的起点;剩下的点是端点。Quartz从第一个点开始一个新的子路径,并将直线段连接到每个端点。

    Arcs

    圆弧。Quartz提供两个创建弧的功能。函数CGContextAddArc创建了一个圆形的曲线段。指定圆的中心、半径和径向角度(以弧度表示)。你可以通过指定一个2的径向角度来创建一个完整的圆。图3-4显示了独立绘制的多条路径。每个路径包含一个随机生成的圆;有的被填满,有的被绘制。
    Figure 3-4 Multiple paths; each path contains a randomly generated circle


    circles.gif

    CGContextAddArcToPoint函数是理想的用于圆角矩形的函数。Quartz使用您提供的端点创建两条切线。您还可以提供Quartz切割弧的圆的半径。圆弧的中心点是两个半径的交点,每个半径都垂直于两条切线中的一条。圆弧的每个端点是其中一条切线上的一个切线点,如图3-5所示。圆圈的红色部分是实际画出来的。
    Figure 3-5 Defining an arc with two tangent lines and a radius


    rounded_corner.gif
    如果当前路径已经包含子路径,则Quartz会将一条从当前点到弧的起始点的直线段追加进来。如果当前路径为空,Quartz将在弧线的起始点创建一个新的子路径,而不添加初始的直线段。
    Curves

    二次曲线和三次贝塞尔曲线是可以指定任意数量的有趣曲线形状的代数曲线。这些曲线上的点是通过对起始点和结束点以及一个或多个控制点应用多项式公式计算出来的。以这种方式定义的形状是向量图形的基础。公式比位数组存储要紧凑得多,而且它的优点是可以在任何分辨率下重新创建曲线。
    图3-6显示了通过独立绘制多条路径创建的各种曲线。每个路径包含一个随机生成的曲线;有的被填满,有的被绘制。
    Figure 3-6 Multiple paths; each path contains a randomly generated curve


    bezier_paths.gif

    在许多描述计算机图形学的数学文本和在线资料中,讨论了多项式公式产生二次曲线和三次贝塞尔曲线的公式,以及如何从公式中生成曲线的细节。这里不讨论这些细节。

    使用CGContextAddCurveToPoint函数从当前点附加一个立方贝塞尔曲线,使用控制点和指定的端点。图3-7显示了由图中所示的当前点、控制点和端点产生的立方贝塞尔曲线。两个控制点的位置决定了曲线的几何形状。如果控制点同时高于起点和终点,曲线向上拱起。如果控制点同时低于起点和终点,曲线会向下弯曲。
    Figure 3-7 A cubic Bézier curve uses two control points


    cubic_bezier_curve.gif

    通过调用函数CGContextAddQuadCurveToPoint并指定控制点和端点,可以从当前点追加一个二次贝塞尔曲线。图3-8显示了使用相同端点但控制点不同的两条曲线。控制点决定曲线拱起的方向。用二次贝塞尔曲线创造出尽可能多有趣的形状是不可能的因为二次曲线只用一个控制点。例如,不可能创建一个交叉使用单一控制点。
    Figure 3-8 A quadratic Bézier curve uses one control point


    quadratic_bezier_curve.gif
    Closing a Subpath

    要关闭当前的子路径,应用程序应该调用CGContextClosePath。该函数将从当前点到子路径起点的线段添加到子路径,并关闭子路径。在子路径的起始点结束的线、弧和曲线实际上并不关闭子路径。必须显式调用CGContextClosePath来关闭子路径。

    有些Quartz函数将路径的子路径视为由应用程序关闭的。这些命令将每个子路径视为应用程序调用CGContextClosePath来关闭它,隐式地在子路径的起始点添加一条线段。

    在关闭子路径之后,如果应用程序发出额外的调用,向路径添加线条、弧线或曲线,Quartz将从刚刚关闭的子路径的起点开始新的子路径。

    Ellipses

    椭圆实质上是一个被压扁的圆。你通过定义两个焦点来创建一个点然后画出所有在一定距离上的点使椭圆上的任何点到一个焦点的距离加上从同一点到另一个焦点的距离总是相同的值。图3-9显示了独立绘制的多条路径。每个路径包含一个随机生成的椭圆;有的被填满,有的被绘制。
    Figure 3-9 Multiple paths; each path contains a randomly generated ellipse


    ellipses.gif

    您可以通过调用CGContextAddEllipseInRect函数向当前路径添加一个椭圆。您提供了一个定义椭圆边界的矩形。Quartz使用一系列贝塞尔曲线来近似椭圆。椭圆的中心是矩形的中心。如果矩形的宽度和高度相等(即为正方形),则椭圆为圆形,其半径等于矩形宽度(或高度)的一半。如果矩形的宽度和高度不相等,则定义椭圆的主轴和小轴。

    添加到路径上的椭圆从移动到操作开始,到关闭子路径操作结束,所有的移动都是顺时针方向。

    Rectangles

    您可以通过调用CGContextAddRect函数向当前路径添加一个矩形。您提供了一个CGRect结构,该结构包含矩形的原点及其宽度和高度。

    添加到路径的矩形以移动到操作开始,以关闭子路径操作结束,所有的移动都以逆时针方向进行。

    通过调用函数CGContextAddRects并提供CGRect结构数组,可以向当前路径添加许多矩形。图3-10显示了独立绘制的多条路径。每个路径包含一个随机生成的矩形;有的被填满,有的被绘制。
    Figure 3-10 Multiple paths; each path contains a randomly generated rectangle


    rectangles.gif
    Creating a Path

    当您想在图形上下文中构造一个路径时,您可以通过调用CGContextBeginPath函数来给Quartz信号。接下来,通过调用CGContextMoveToPoint函数,为路径中的第一个形状或子路径设置起点。在建立第一个点之后,可以在路径中添加直线、弧线和曲线,记住以下几点:
    1、在开始新路径之前,调用函数CGContextBeginPath。
    2、从当前点开始画线、弧和曲线。空路径没有当前点;您必须调用3、CGContextMoveToPoint来设置第一个子路径的起始点,或者调用一个隐式执行此操作的便利函数。
    4、当您想在路径中关闭当前子路径时,调用函数CGContextClosePath来将一个段连接到子路径的起始点。后续路径调用开始一个新的子路径,即使您没有显式地设置一个新的起点。
    5、在绘制弧时,Quartz在当前点和弧的起始点之间划一条线。
    添加椭圆和矩形的石英例程向路径添加一个新的封闭子路径。
    6、您必须调用绘制函数来填充或描边路径,因为创建路径不会绘制路径。详细信息请参见绘制路径。

    在绘制路径之后,它将从图形上下文刷新。你可能不想这么容易迷路,尤其是当它描述了一个复杂的场景,你想一遍又一遍地使用。因此,Quartz提供了两种数据类型来创建可重用路径—cgpathref和CGMutablePathRef。您可以调用CGPathCreateMutable函数来创建一个可变的CGPath对象,您可以向其添加直线、弧线、曲线和矩形。Quartz提供了一组CGPath函数,它们与构建块中讨论的函数并行。路径函数操作CGPath对象而不是图形上下文。这些函数是:
    CGPathCreateMutable取代CGContextBeginPath
    CGPathMoveToPoint取代 CGContextMoveToPoint
    CGPathAddLineToPoint取代CGContextAddLineToPoint
    CGPathAddCurveToPoint取代CGContextAddCurveToPoint
    CGPathAddEllipseInRect取代 CGContextAddEllipseInRect
    CGPathAddArc取代 CGContextAddArc
    CGPathAddRect取代 CGContextAddRect
    CGPathCloseSubpath取代 CGContextClosePath
    有关路径函数的完整列表,请参阅Quartz 2D参考集合。

    当您想要将路径附加到图形上下文时,您可以调用CGContextAddPath函数。该路径在Quartz绘制之前一直停留在图形上下文中。您可以通过调用CGContextAddPath再次添加路径。

    注意:通过调用函数CGContextReplacePathWithStrokedPath,可以用路径的描边版本替换图形上下文中的路径。

    Painting a Path

    您可以通过描边或填充或两者都画出当前路径。抚摸画出一条横跨在道路上的线条。填充绘制路径中包含的区域。Quartz具有一些函数,可以让您描边路径、填充路径或同时描边和填充路径。描边线的特征(宽度、颜色等等)、填充颜色以及Quartz用于计算填充区域的方法都是图形状态的一部分(参见图形状态)。

    影响描边的参数

    可以通过修改表3-1中列出的参数来影响路径的遍历方式。这些参数是图形状态的一部分,这意味着您为一个参数设置的值会影响所有后续的笔画操作,直到您将参数设置为另一个值为止。


    EC829D0C-3537-4D8A-8331-7FD00A0C29F0.png

    line width是线的总宽度,用用户空间的单位表示。这条线横跨在道路上,两边各占总宽度的一半。

    line join指定Quartz如何在连接的线段之间绘制连接。Quartz支持表3-2中描述的行连接样式。默认的样式是miter join。


    6E78450A-9A5F-45AE-BDEA-B94709045BBA.png

    line cap指定了CGContextStrokePath用来绘制线端点的方法。Quartz支持表3-3中描述的线帽样式。默认的样式是屁股盖。


    A433061F-4C6B-4EA1-8A07-C3D0A45EE412.png
    封闭子路径将起始点作为连接线段之间的连接点;起始点是使用选定的行连接方法呈现的。相反,如果通过添加连接到起始点的线段来关闭路径,则路径的两端都使用所选的线盖方法绘制。

    line dash pattern允许你沿着描边路径画一条分段的线。通过将dash数组和dash phase指定为CGContextSetLineDash的参数,可以控制dash分段的大小和位置:

    void CGContextSetLineDash (
        CGContextRef ctx,
        CGFloat phase,
        const CGFloat lengths[],
        size_t count
    );
    

    length参数的元素指定了破折号的宽度,在绘制和未绘制的线段之间交替使用。相位参数指定dash模式的起点。图3-11显示了一些线划线模式。


    225E4EBC-1B2C-404A-8A4A-481B70699CE0.png

    笔画颜色空间决定了笔画颜色值如何由Quartz解释。还可以指定封装颜色和颜色空间的Quartz颜色(CGColorRef数据类型)。有关设置颜色空间和颜色的更多信息,请参阅颜色和颜色空间。

    Functions for Stroking a Path
    Quartz提供了如表3-4所示的用于抚摸当前路径的函数。一些是用于描边矩形或椭圆的方便函数。 7B095ABF-4CA0-4D66-BE7A-8D87786265EE.png

    CGContextStrokeLineSegments函数相当于以下代码:

    CGContextBeginPath (context);
    for (k = 0; k < count; k += 2) {
        CGContextMoveToPoint(context, s[k].x, s[k].y);
        CGContextAddLineToPoint(context, s[k+1].x, s[k+1].y);
    }
    CGContextStrokePath(context);
    

    当您调用CGContextStrokeLineSegments时,您将线段指定为点数组,以对的形式组织。每一对由线段的起始点和线段的结束点组成。例如,数组中的第一个点指定第一行的起始位置,第二个点指定第一行的结束位置,第三个点指定第二行的起始位置,等等。

    Filling a Path

    当您填充当前路径时,Quartz就好像路径中包含的每个子路径都是关闭的。然后它使用这些封闭子路径并计算要填充的像素。Quartz表有两种计算填充面积的方法。简单的路径,例如椭圆和矩形,有一个定义明确的区域。但是,如果您的路径由重叠部分组成,或者路径包含多个子路径,比如图3-12所示的同心圆,则可以使用两个规则来确定填充区域。
    你可以选择使用奇偶法则。要确定是否应该绘制特定的点,从该点开始,画出超出该点界限的线。计算直线穿过的路径段数。如果结果是奇数,则绘制该点。如果结果是偶数,则不绘制该点。绘制路径段的方向不影响结果。正如您在图3-12中所看到的,绘制每个圆的方向并不重要,填充将始终如图所示。


    F92CA294-0597-4903-A6A2-5C868B85A78F.png

    Quartz为填充当前路径提供了表3-5所示的函数。一些是用于描边矩形或椭圆的方便函数。


    1EFC7E20-BE25-4161-8B7C-10276B320CC0.png
    Setting Blend Modes

    混合模式指定Quartz如何应用绘制背景。Quartz默认使用普通的混合模式,它使用以下公式将前景画和背景画结合起来:

    result = (alpha * foreground) + (1 - alpha) * background
    

    Color and Color Spaces提供了关于颜色的alpha组件的详细讨论,它指定了颜色的不透明度。对于本节中的示例,您可以假设颜色是完全不透明的(alpha值= 1.0)。对于不透明的颜色,当你使用普通的混合模式作画时,你在背景上画的任何东西都会完全模糊背景。

    您可以通过调用函数CGContextSetBlendMode来设置混合模式以实现各种效果,并传递适当的混合模式常量。请记住,混合模式是图形状态的一部分。如果在更改混合模式之前使用了函数CGContextSaveGState,那么调用函数cgcontext trestoregstate将混合模式重置为正常模式。
    本节的其余部分显示了将图3-13所示的矩形绘制到图3-14所示矩形之上的结果。在每种情况下(图3-15到图3-30),背景矩形都是使用普通混合模式绘制的。然后通过使用适当的常量调用CGContextSetBlendMode函数来更改混合模式。最后,绘制前景矩形。


    屏幕快照 2018-08-27 上午10.36.49.png
    屏幕快照 2018-08-27 上午10.37.26.png

    注意:您还可以使用混合模式来组合两个图像,或者将图像与任何已经绘制到图形上下文的内容进行组合。在图像中使用混合模式提供了如何将混合模式用于复合图像的信息,并显示了对两个图像应用混合模式的结果。

    Normal Blend Mode(正常的混合模式)

    因为普通的混合模式是默认的混合模式,所以您可以使用常量CGContextSetBlendMode调用函数CGContextSetBlendMode,只有将混合模式重置为默认模式,才能使用其他混合模式常量。图3-15显示了使用普通混合模式绘制图3-13比图3-14的结果。


    屏幕快照 2018-08-27 上午10.42.37.png
    Multiply Blend Mode

    多重混合模式指定将前景图像样本与背景图像样本叠加。产生的颜色至少和两个产生的样本颜色一样暗。图3-16显示了使用多重混合模式绘制图3-13 /图3-14的结果。要使用这种混合模式,请使用常量CGContextSetBlendMode调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 上午10.46.13.png
    Screen Blend Mode

    屏幕混合模式指定将前景图像样本的逆与背景图像样本的逆相乘。产生的颜色至少和两个产生的样例颜色一样轻。图3-17显示了使用屏幕混合模式绘制图3-13比图3-14的结果。要使用此混合模式,请使用常量kCGBlendModeScreen调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 上午10.47.37.png
    Overlay Blend Mode

    叠加混合模式指定根据背景颜色,将前景图像样本与背景图像样本相叠加或遮蔽。背景颜色与前景颜色混合以反映背景的明度或暗度。图3-18显示了使用叠加混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,可以使用常量kCGBlendModeOverlay调用CGContextSetBlendMode函数。


    屏幕快照 2018-08-27 上午10.52.28.png
    Darken Blend Mode

    指定通过选择较暗的样本(从前景图像或背景图像)来创建复合图像样本。背景图像样本被任何较暗的前景图像样本所取代。否则,背景图像样本将保持不变。图3-19显示了使用暗混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,可以使用常量kCGBlendModeDarken调用CGContextSetBlendMode函数。


    屏幕快照 2018-08-27 上午10.55.23.png
    Lighten Blend Mode

    指定通过选择较轻的样本(从前景或背景)来创建复合图像样本。结果是,背景图像样本被任何较轻的前景图像样本所取代。否则,背景图像样本将保持不变。图3-20显示了使用变淡混合模式绘制图3-13比图3-14的结果。要使用此混合模式,请使用常量kcgblendmodeli调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 上午10.56.57.png
    Color Dodge Blend Mode

    指定使背景图像样本变亮以反映前景图像样本。指定黑色的前景图像示例值不会产生更改。图3-21显示了使用颜色减淡混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,可以使用常量kCGBlendModeColorDodge调用CGContextSetBlendMode函数。


    屏幕快照 2018-08-27 上午10.57.59.png
    Color Burn Blend Mode

    指定使背景图像样本变暗以反映前景图像样本。指定白色的前景图像示例值不会产生更改。图3-22显示了使用颜色加深混合模式绘制图3-13比图3-14的结果。要使用此混合模式,请使用常量kcgblendmodecolburn调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 上午10.59.10.png
    Soft Light Blend Mode

    根据前景图像样本颜色的不同,指定颜色变暗或变浅。如果前景图像样本的颜色比50%的灰度浅,背景会变浅,类似于躲避。如果前景图像的样本颜色比50%的灰度深,背景会变暗,类似于燃烧。如果前景图像的样本颜色等于50%的灰度,背景不会改变。与纯黑或纯白相等的图像样本会产生较暗或较浅的区域,但不会产生纯黑或纯白。整体效果与你在前景图像上使用漫射聚光灯所达到的效果相似。用这个来给场景添加高光。图3-23显示了使用柔光混合模式绘制图3-13比图3-14的结果。要使用此混合模式,请使用常量kCGBlendModeSoftLight调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 上午11.00.15.png
    Hard Light Blend Mode
    指定相乘或屏幕颜色,取决于前景图像样本颜色。如果前景图像样本的颜色比50%的灰度浅,背景会变浅,类似于筛选。如果前景图像的样本颜色比50%的灰度深,背景会变暗,类似于相乘。如果前景图像样本颜色为50%灰度,则前景图像不改变。等于纯黑或纯白的图像样本结果是纯黑或纯白。整体效果类似于你在前景图像上发出强烈的聚光灯所能达到的效果。用这个来给场景添加高光。图3-24显示了使用强光混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,请使用常量kCGBlendModeHardLight调用函数 屏幕快照 2018-08-27 上午11.01.10.png
    Difference Blend Mode

    指定从背景图像样本颜色中减去前景图像样本颜色,或者反过来,这取决于哪个样本的亮度值更大。前景图像样本值为黑色不会产生变化;白色反转背景颜色的值。图3-25显示了使用差异混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,请使用常量kCGBlendModeDifference调用CGContextSetBlendMode函数。


    屏幕快照 2018-08-27 上午11.02.00.png
    Exclusion Blend Mode

    指定类似于kCGBlendModeDifference产生的效果,但具有较低的对比度。前景图像样本值为黑色不会产生变化;白色反转背景颜色的值。图3-26显示了使用排除混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,请使用常量kCGBlendModeExclusion调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 上午11.03.19.png
    Hue Blend Mode

    指定将背景的亮度和饱和度值与前景图像的色调一起使用。图3-27显示了使用色调混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,请使用常量kCGBlendModeHue调用CGContextSetBlendMode函数。

    Saturation Blend Mode

    指定在前景图像的饱和度下使用背景的亮度和色调值。没有饱和度的背景区域(即纯灰色区域)不会产生变化。图3-28显示了使用饱和度混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,使用常量kCGBlendModeSaturation调用函数CGContextSetBlendMode即可。


    屏幕快照 2018-08-27 下午12.33.41.png
    Color Blend Mode

    指定将背景的亮度值与前景图像的色调和饱和度值一起使用。这种模式保留了图像中的灰度。您可以使用此模式为单色图像着色或为彩色图像着色。图3-29显示了使用颜色混合模式绘制图3-13比图3-14的结果。要使用此混合模式,请使用常量kCGBlendModeColor调用函数CGContextSetBlendMode。


    屏幕快照 2018-08-27 下午12.34.30.png
    Luminosity Blend Mode

    指定使用带有前景图像亮度的背景色调和饱和度。此模式创建的效果与kCGBlendModeColor创建的效果相反。图3-30显示了使用光度混合模式绘制图3-13比图3-14的结果。要使用这种混合模式,请使用常量kcgblendmodelosity来调用CGContextSetBlendMode函数。


    屏幕快照 2018-08-27 下午12.35.15.png
    Clipping to a Path

    当前的剪切区域是从一个用作遮罩的路径创建的,允许您将不希望绘制的页面部分屏蔽掉。例如,如果您有一个非常大的位图图像,并且想只显示它的一小部分,您可以设置剪切区域来只显示您想显示的部分。

    当您绘制时,Quartz只在剪切区域内呈现绘制。在剪切区域的闭合子路径内的绘制是可见的;发生在剪切区域的闭合子路径之外的绘制不是。
    当最初创建图形上下文时,剪切区域包括上下文的所有可绘制区域(例如,PDF上下文的媒体框)。通过设置当前路径,然后使用剪切函数而不是绘图函数来更改剪切区域。剪切函数将当前路径的填充区域与现有的剪切区域相交。因此,您可以与裁剪区域相交,缩小图片的可见区域,但不能增加裁剪区域的面积。

    剪切区域是图形状态的一部分。要将剪切区域恢复到以前的状态,可以在剪切之前保存图形状态,并在剪切完成后恢复图形状态。
    清单3-1显示了一个代码片段,该代码片段设置了一个圆形的剪切区域。这段代码使绘图被裁剪,类似于图3-3所示。(另一个例子,请参阅渐变章节中的上下文剪辑。)

    CGContextBeginPath (context);
    CGContextAddArc (context, w/2, h/2, ((w>h) ? h : w)/2, 0, 2*PI, 0);
    CGContextClosePath (context);
    CGContextClip (context);
    
    屏幕快照 2018-08-27 下午12.39.49.png

    相关文章

      网友评论

        本文标题:Core Graphics 之 Paths (四)

        本文链接:https://www.haomeiwen.com/subject/pqtniftx.html