0

我创建了一个视图,并在我的 draw rect 方法中创建路径,具体取决于用户对滑块的操作。使用标准颜色,一切正常,看起来非常漂亮。我正在尝试遵循来自苹果的代码片段,该片段显示了如何在此链接上将模式绘制到矩形中: Apple 绘图指南

该示例显示了如何使用所需的模式创建函数回调,然后调用附加方法来绘制矩形。如果我按照我的 rect 编写的代码调用代码,它将按照我的预期绘制我的模式,但是,我不想填充我的 rect ,我想填充 rect 中的指定路径。如果我将绘图方法中的调用从 CGContextFillRect 更改为 CGContextFillPath,它就不起作用。我确定我忽略了一些东西来修改此代码以使其执行我想要的操作。

我的回调模式是一个简单的棋盘:

代码:

// Call Back function for Graphics Pattern

#define PATTERN_SIZE 10

void patternSpec(void *info , CGContextRef pContext){

    NSLog(@"patternSpec Callback Called");
    CGFloat subUnit = PATTERN_SIZE / 2;

    CGRect square1 = {{0,0}, {subUnit, subUnit}},
    square2 = {{subUnit, subUnit}, {subUnit, subUnit}},
    square3 = {{0 , subUnit}, {subUnit, subUnit}},
    square4 = {{subUnit , 0}, {subUnit, subUnit}};


    CGContextSetRGBFillColor(pContext, 1.0, 0.0, 0.0, 1.0 );
    CGContextFillRect(pContext, square1);

    CGContextSetRGBFillColor(pContext, 1.0, 0.0, 0.0, 1.0 );
    CGContextFillRect(pContext, square2);

    CGContextSetRGBFillColor(pContext, 0.0, 0.0, 0.0, 1.0 );
    CGContextFillRect(pContext, square3);

    CGContextSetRGBFillColor(pContext, 0.0, 0.0, 0.0, 1.0 );
    CGContextFillRect(pContext, square4);

}

// Method that draws the pattern

static void drawPattern (CGContextRef myContext)
{
    NSLog(@"drawPattern Called ");
    CGPatternRef    pattern;
    CGColorSpaceRef patternSpace;
    CGFloat         alpha = 1.0;
    //width, height;

    static const CGPatternCallbacks callbacks = {0, &patternSpec, NULL};

    CGContextSaveGState (myContext);
    patternSpace = CGColorSpaceCreatePattern (NULL);// 6
    CGContextSetFillColorSpace (myContext, patternSpace);// 7
    CGColorSpaceRelease (patternSpace);// 8

    pattern = CGPatternCreate (NULL,CGRectMake (0, 0, PATTERN_SIZE, PATTERN_SIZE),
    CGAffineTransformIdentity, PATTERN_SIZE, PATTERN_SIZE,
    kCGPatternTilingConstantSpacing true, &callbacks);

    CGContextSetFillPattern (myContext, pattern, &alpha);// 17
    CGPatternRelease (pattern);// 18
    //CGContextFillRect(myContext, rect);
    CGContextDrawPath(myContext, kCGPathFill);
    CGContextRestoreGState (myContext);

}

这是我想调用例程的代码片段:

CGContextSetLineWidth(context, .7);
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);


// Standard non-inverted view scenario.
CGContextBeginPath(context);

CGContextMoveToPoint(context, 0.00 , bMargin);      
CGContextAddLineToPoint(context, highPX - curveSP , bMargin);
[self addCurve:context startX:highPX startY:bMargin radius:bo curveSp:curveSP curveDir:FL_BL];

CGContextAddLineToPoint(context, highPX, ((h - tMargin) - curveSP) );
[self addCurve:context startX:highPX startY: (h - tMargin) radius:bo curveSp:curveSP curveDir:FL_TL];


CGContextAddLineToPoint(context, (lowPX - curveSP), (h - tMargin) );
[self addCurve:context startX: lowPX  startY: (h - tMargin) radius:bo curveSp:curveSP curveDir:FL_TR];

CGContextAddLineToPoint(context, lowPX, (bMargin + curveSP) );      
[self addCurve:context startX:lowPX startY: bMargin  radius:bo curveSp:curveSP curveDir:FL_BR];

CGContextAddLineToPoint(context, w, bMargin);

//CGContextDrawPath(context, nonInvertedView);

CGContextDrawPath(context, kCGPathStroke);
// fill with pattern
drawPattern(context);

实际的苹果示例还在绘图方法中包含一个 NSRect 参数,但由于我不想填充矩形,我想我可以省略它。不过不确定。

谢谢

4

2 回答 2

1

CGContextDrawPath重置当前路径。(他们曾经在某个地方提到过,但我在快速搜索中找不到。)

在描边之前保存图形状态,然后在填充图案之前恢复。

(我假设您专门尝试通过抚摸然后填充一半以上来获得外部笔划。如果您想要或可以接受居中的笔划,kCGPathFillStroke只需一次CGContextDrawPath调用即可完成这项工作。)

于 2013-04-26T22:45:24.863 回答
0

所以这里有一个更新:我不完全理解发生了什么,但是如果我将 drawPattern 方法中的代码放到一个带有空矩形的测试应用程序中,它会像它应该的那样绘制。如果我将代码放入用于将路径绘制到视图中的方法中,我会得到非常奇怪的行为;它甚至试图重绘它甚至不应该知道的视图控制器的部分。

一旦我删除了 CGContextSaveGState()、CGColorSpaceRelease()、CGPatternRelease() 和 CGContextRestoreGState(),代码就开始做我想要的。我将方法修改为:

static void drawPattern(CGContextRef *pContext){

    static CGPatternRef    pattern;
    static CGColorSpaceRef patternSpace;
    static CGFloat         alpha = 1.0;


static const CGPatternCallbacks callbacks = {0, &patternSpec, NULL};

    patternSpace = CGColorSpaceCreatePattern (NULL);
    CGContextSetFillColorSpace (pContext, patternSpace);

    pattern = CGPatternCreate (NULL, 
               CGRectMake (0, 0, PATTERN_SIZE, PATTERN_SIZE),
               CGAffineTransformIdentity,
               PATTERN_SIZE, 
               PATTERN_SIZE, 
               kCGPatternTilingConstantSpacing,
               true, &callbacks);


     CGContextSetFillPattern (pContext, pattern, &alpha);   

}

现在我可以调用定义的模式,或者设置定义的填充颜色:

CGContextSetFillColor(context);
or:    
drawPattern(context);

我将不胜感激,因为我想知道省略其中一些 saveState 或 Release 方法是否是诸如内存泄漏之类的问题。

谢谢

于 2013-04-29T16:41:16.010 回答