2009-04-22 67 views
2

作爲我的應用程序中的其中一個視圖的背景,我想在其框架內繪製一個相當簡單的矩形邊框。這基本上是一個矩形漸變:圍繞框架的黑線,漸變爲約10-20像素的白色。不幸的是,據我所知,Core Graphics不提供矩形漸變(使用CGGradientCGShading)。所以我想知道最好的方法是什麼。使用Quartz 2D/Core Graphics完成此繪圖的最佳方法?

兩個發生的對我說:

  1. 繪製一系列同心矩形的,在顏色以後每次一個打火機,並通過1px的每一側的插圖。我想不出一個更簡單的方法,但我必須自己完成所有的梯度計算,並且可能需要很多圖形操作。
  2. 以線性模式使用CGGradient,每邊一次。但爲了達到這個目的,我想我需要先爲每一邊設置一個梯形裁剪區域,以便在角落處漸變。

好像有應該是使用路徑撫摸做到這一點的一種方式,但它似乎並不像有一種方法來定義不同的真實面向每邊的圖案。

+0

使用CGGradient每條邊會更快,但如果這仍然太慢,你可以使用一個UIImage作爲高速緩存(提請UIImage的一次,然後繪製圖像在需要時查看) – rpetrich 2009-04-22 14:58:51

+0

呀,我認爲無論我採用什麼方法來繪製圖片,緩存圖片和結果都可能是一個好主意。但我有點像程序化繪圖的想法,而不是在應用程序中發佈PNG。 – 2009-04-23 02:12:27

回答

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

這樣的事情也可以工作。基本上:不是使用剪切路徑,而是簡單地使用blendmode。 ,在這個例子中,漸變被緩存在CGLayer中。

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