2013-04-26 59 views
0

我创建了一个视图,并且在绘制矩形方法中,我根据用户使用滑块创建路径。使用标准颜色,一切正常,看起来非常好。我试图按照苹果的代码片段展示了如何在这个环节上绘制图案成矩形: Apple Drawing Guide如何使用Quartz中的模式填充路径

的例子展示了如何创建一个回调函数与所需的图案,然后一个额外的方法调用绘制该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参数,但由于我不想填充矩形,我想我可以忽略它。不确定。

谢谢

回答

1

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

在笔画前保存图形状态,然后在填充图案之前进行还原。

(我假设你特别想获得通过抚摸,然后填充超过一半的外中风。如果你希望,也可以接受一个居中的行程,kCGPathFillStroke将做的工作有一个CGContextDrawPath电话。)

+0

感谢您的意见。请检阅我自己的回答和评论。为了回答你的问题,我试图在路径上保留一个简单的黑色笔画,并使用该图案作为填充。抚摸路径并不是一个问题,它取代了一个标准的颜色填充模式,这是挑战。我一直在我的调用代码中使用绘制路径。 – Miek 2013-04-29 16:44:25

+1

@Miek:'kCGPathFillStroke'会做到这一点。两个都不使用相同的颜色;它使用描边颜色/图案进行描边,填充颜色/图案进行填充。 – 2013-04-29 16:59:01

+0

是的,你是对的,我一直在做我的应用程序。这更多的是setFill或setPattern问题。如果您试图暗示我可以将drawPath放入drawPattern方法并取得成功,那么我确信我已经尝试过并且没有运气。 – Miek 2013-04-29 17:03:20

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方法中的一些问题,例如内存泄漏。

谢谢

+0

是的,不释放你拥有的东西是你如何泄漏它们。保存和恢复gstate不是内存问题;这是一个正确性问题。我不认为它需要围绕模式回调的全部内容进行讨论和讨论。 – 2013-04-29 16:59:35