2013-04-26 51 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