2

作为我的应用程序中一个视图的背景,我想在其框架内绘制一个相当简单的矩形边框。这本质上是一个矩形渐变:框架周围有一条黑线,在大约 10-20 像素处逐渐变白。不幸的是,据我所知,Core Graphics 不提供矩形渐变(使用CGGradientCGShading)。所以我想知道最好的方法是什么。

我想到的两个:

  1. 绘制一系列同心矩形,每个矩形颜色较浅,每边插入 1px。我想不出更简单的方法,但我必须自己做所有的梯度计算,而且可能是很多图形操作。
  2. 在线性模式下使用CGGradient,每边一次。但是为了这个工作,我想我需要先为每一边设置一个梯形剪裁区域,以便渐变在角落处斜接。

似乎应该有一种方法可以使用路径抚摸来做到这一点,但似乎没有一种方法可以定义一种在每一侧都有不同方向的模式。

4

2 回答 2

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];
于 2009-04-22T15:40:26.460 回答
0

像这样的东西也可以工作。基本上:而不是使用剪切路径,只需使用混合模式。在本例中,渐变缓存在 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);
于 2009-11-23T16:51:11.033 回答