2013-04-26 3 views
0

뷰를 만들었고 그리기 rect 메소드에서 사용자가 슬라이더를 사용하여 수행하는 작업에 따라 경로를 만듭니다. 표준 색상을 사용하면 모든 것이 작동하고 매우 멋지게 보입니다. 이 링크에서 패턴을 직사각형으로 그리는 법을 보여주는 코드 스 니펫을 따르려고합니다. Apple Drawing GuideQuartz에서 패턴으로 패스를 채우는 방법

이 예제는 원하는 패턴과 함수 호출을 만드는 방법을 보여줍니다. rect. 필자가 rect에서 작성한 코드를 호출하면 필자의 예상대로 패턴을 그릴 것입니다. 그러나 rect를 채우고 싶지는 않습니다. rect에 지정된 경로를 채우고 싶습니다. 드로잉 메서드에서 CGContextFillRect에서 CGContextFillPath로 호출을 변경하면 작동하지 않습니다. 나는 내가 원하는 것을하기 위해이 코드를 수정하기 위해 간과 할 부분이있을 것이라고 확신한다.

내 콜백 패턴은 간단한 바둑판입니다 :

코드 :

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); 

실제를 : 여기에

// 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); 

} 

내가 루틴 호출하고자하는 코드의 조각이다 apple 예제는 또한 드로잉 메서드에 NSRect arg를 포함하고 있습니다. 그러나 rect를 채우고 싶지 않기 때문에 생략 할 수 있다고 생각했습니다. 확실하지.

감사

답변

1

CGContextDrawPath는 현재 경로를 재설정합니다. (그들은 어딘가에서 언급 했었지만 빠른 검색에서 찾을 수 없었습니다.)

획을 칠하기 전에 그래픽 상태를 저장 한 다음 패턴으로 채우기 전에 복원하십시오.

은 (난 당신이 특별히 절반 이상 충전 후 쓰다듬어에 의해 외부 스트로크를 얻기 위해 노력하고 가정합니다. 당신이 원하는 또는 중앙에 뇌졸중을 받아 들일 수 있다면, kCGPathFillStroke는 하나의 CGContextDrawPath 호출로 일을 할 것입니다.)

+0

감사합니다. 본인의 자기 답과 의견을 검토하십시오. 귀하의 질문에 대답하기 위해, 나는 경로에 간단한 검은 획을 유지하고 채우기로 패턴을 사용하려고합니다. 경로를 스트로킹하는 것은 문제가 아니며 표준 색상 채우기를 패턴으로 대체합니다.내 전화 코드에서 draw 경로를 사용하고 있습니다. – Miek

+1

@Miek :'kCGPathFillStroke'가 그렇게 할 것입니다. 둘 다 동일한 색상을 사용하지는 않습니다. 스트로크 색상/패턴을 칠하고 채우기 색상/패턴을 사용하여 채 웁니다. –

+0

네가 맞아, 내 앱에서 그렇게 해왔다. 이는 setFill 또는 setPattern 문제에 더 가깝습니다. 만약 당신이 drawPattern 메소드에 drawPath를 넣을 수 있었고 성공했다는 것을 암시하려는 경우, 나는 그것을 시도하고 행운이 없었다고 확신합니다. – Miek

0

업데이트를 heres : 나는 무슨 일이 일어나고 있는지 완전히 이해하지 못한다. 그러나 drawPattern 메서드의 코드를 빈 rect가있는 테스트 응용 프로그램에 드롭하면 꼭 그렇게해야한다. 뷰에 경로를 그리기 위해 코드를 내 메소드에 삽입하면 매우 이상한 동작을 보입니다. 그것은 심지어 알지 못하는 뷰 컨트롤러의 부분을 다시 그리기 위해 시도합니다.

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); 

} 

를 I 중 하나를 수행 할 수 있습니다 정의 된 패턴을 전화, 또는 정의 채우기 색상 설정 : 내가 알고 싶습니다 때문에 나는이에 입력을 부탁드립니다

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

을 이러한 saveState 또는 Release 메소드 중 일부를 생략하면 메모리 누수와 같은 문제가 발생합니다.

감사합니다.

+0

예, 소유하고있는 물건을 공개하지 않으면 누출되는 것입니다. gstate를 저장하고 복원하는 것은 메모리 문제가 아닙니다. 그것은 정확성 문제입니다. 패턴 콜백의 전체 내용을 gsave하고 grestore 할 필요는 없다고 생각합니다. –

관련 문제