2009-04-22 65 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);