2009-04-22 3 views
2

내 애플 리케이션에서 뷰 중 하나에 대한 배경으로, 그 프레임 안에 꽤 간단한 사각형 테두리를 그릴 싶습니다. 이것은 본질적으로 사각 그라디언트 일 것입니다 : 프레임 주위에 검은 선이 10-20 픽셀 정도 흰색으로 희미 해집니다. 불행히도 Core Graphics는 사각형 그라디언트 (CGGradient 또는 CGShading)를 제공하지 않습니다. 그래서 최선의 접근 방법이 무엇인지 궁금합니다. 나에게 발생Quartz 2D/Core Graphics로이 그림을 완성하는 가장 좋은 방법은?

2 :

  1. 동심 일련의 사각형 그리기, 이후의 각 하나의 색상 라이터, 각면에 1 x 1 픽셀에 의해 세트입니다. 더 간단한 접근법을 생각할 수는 없지만 모든 그라디언트 계산을 직접 수행해야하며 많은 그래픽 작업이 필요할 수 있습니다.
  2. 선형 모드에서 각면에 대해 한 번씩 CGGradient을 사용하십시오. 그러나 이것이 작동하려면 먼저 각면에 사다리꼴 클리핑 영역을 설정해야하므로 그라디언트가 모퉁이에서 잘릴 수 있습니다. 이 일을 쓰다듬어 경로를 사용하는 방법이 있어야처럼

는 보이지만 각면에서 다르게 지향있어 패턴을 정의하는 방법이처럼은 보이지 않는다.

+0

빨리 될 것입니다,하지만 당신은 그래 – rpetrich

+0

를 그 여전히 너무 느린 경우 (한 번있는 UIImage에 그린 다음 필요한 뷰에 이미지를 그릴) 캐시로있는 UIImage를 사용할 수 있습니다 드로잉에 어떤 접근 방식을 사용하든 이미지를 캐싱하는 것이 좋은 아이디어 일 것입니다. 그러나 나는 앱에서 PNG를 선적하기보다는 절차 적으로 드로잉을하는 아이디어와 비슷합니다. –

답변

3

내가 옵션 # 2로 갈 것 :

사용 CGGradient를 선형 모드에서 한 번 각면에 대해. 그러나 이것이 작동하려면 먼저 각면에 사다리꼴 클리핑 영역을 설정해야하므로 그라디언트가 모퉁이에서 잘릴 수 있습니다.

사다리꼴 영역을 만드는 데 NSBezierPath을 사용하면 상당히 간단 할 것이며 그리기 작업을 네 번만 수행하면됩니다.

다음은 왼쪽 사다리꼴 영역을 만들기위한 기본 코드의이 같은

NSRect outer = [self bounds]; 
NSPoint outerPoint[4]; 
outerPoint[0] = NSMakePoint(0, 0); 
outerPoint[1] = NSMakePoint(0, outer.size.height); 
outerPoint[2] = NSMakePoint(outer.size.width, outer.size.height); 
outerPoint[3] = NSMakePoint(outer.size.width, 0); 

NSRect inner = NSInsetRect([self bounds], borderSize, borderSize); 
NSPoint innerPoint[4]; 
innerPoint[0] = inner.origin; 
innerPoint[1] = NSMakePoint(inner.origin.x, 
          inner.origin.y + inner.size.height); 
innerPoint[2] = NSMakePoint(inner.origin.x + inner.size.width, 
          inner.origin.y + inner.size.height); 
innerPoint[3] = NSMakePoint(inner.origin.x + inner.size.width, 
          inner.origin.y); 

NSBezierPath leftSidePath = [[NSBezierPath bezierPath] retain]; 
[leftSidePath moveToPoint:outerPoint[0]]; 
[leftSidePath lineToPoint:outerPoint[1]]; 
[leftSidePath lineToPoint:innerPoint[1]]; 
[leftSidePath lineToPoint:innerPoint[0]]; 
[leftSidePath lineToPoint:outerPoint[0]]; 

// ... etc. 

[leftSidePath release]; 
+0

(분명히?) iPhone (또는 Mac)에서 많은 그래픽 프로그래밍을 아직하지 않은 사람이라면 ... NSBezierPath를 선호하는 이유가 있습니까? 필자가 본 대부분의 예는 Core Graphics API에 집중되어 있습니다. –

+0

글쎄요, 이전에 사용했기 때문에 여기에서 사용했습니다. :) Core Graphics가 더 잘 할 수 있다는 것은 전적으로 가능합니다. 시도해볼 때 아무런 해가되지 않지만 측정 가능한 성능 향상이 있는지 (또는 실제로 필요한 경우) 코드를 프로파일 링해야합니다. –

+0

이것은 정확히 내가 결국 생각한 코드는 아니지만 사소한 것은 비슷합니다. 네 개의 사다리꼴을 그릴 때보 다 더 나은 해결책을 제시하지 못했습니다. –

0

무엇인가도 작동 할 수있다. 기본적으로 : 클리핑 패스를 사용하는 대신 간단히 blendmode를 사용하십시오. 이고이 예제에서는 그라디언트가 CGLayer에 캐시됩니다. 각 에지에 대한 CGGradient를 사용

CGContextRef ctx = UIGraphicsGetCurrentContext(); 
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB(); 

CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); 
CGContextFillRect(ctx,self.bounds); 

CGFloat w = self.bounds.size.width; 
CGFloat h = self.bounds.size.height; 
CGFloat dh = (w-h)/2; 

CGLayerRef l = CGLayerCreateWithContext(ctx,CGSizeMake(h,48.0f),NULL); 
CGContextRef lctx = CGLayerGetContext(l); 

float comp[] = { .2,.5,1.0,1.0,1.0,1.0,1.0,1.0}; 
CGGradientRef gradient = CGGradientCreateWithColorComponents(cspace, comp, NULL, 2); 
CGContextDrawLinearGradient(lctx, gradient,CGPointMake(0,0),CGPointMake(0,48), 0); 

CGContextSaveGState(ctx); 
CGContextSetBlendMode(ctx,kCGBlendModeDarken); 
for(int n=1;n<5;n++) 
{ 
    CGContextTranslateCTM(ctx,w/2.0,h/2.0); 
    CGContextRotateCTM(ctx, M_PI_2); 
    CGContextTranslateCTM(ctx,-w/2.0,-h/2.0); 
    CGContextDrawLayerAtPoint(ctx,CGPointMake((n%2)*dh,(n%2)*-dh),l); 
} 
CGContextRestoreGState(ctx);