2

アプリのビューの1つの背景として、フレームのすぐ内側にかなり単純な長方形の境界線を描画したいと思います。これは基本的に長方形のグラデーションになります。フレームの周りの黒い線は、約10〜20ピクセルの白にフェードします。残念ながら、私が知る限り、Core Graphicsは長方形のグラデーションを提供していません(またはのいずれCGGradientCGShading)。だから私は最善のアプローチは何だろうかと思っています。

私に起こる2つ:

  1. 一連の同心の長方形を描画します。それぞれの長方形は色が薄くなり、各辺に1pxずつはめ込まれます。これ以上簡単な方法は考えられませんが、すべてのグラデーション計算を自分で行う必要があり、多くのグラフィック操作が必要になる可能性があります。
  2. CGGradient線形モードで、各サイドに1回使用します。しかし、これが機能するためには、最初に両側に台形のクリッピング領域を設定して、グラデーションがコーナーで留め継ぎされるようにする必要があると思います。

パスストロークを使用してこれを行う方法があるはずですが、両側で異なる方向に向けられたパターンを定義する方法はないようです。

4

2 に答える 2

3

私はオプション#2で行きます:

線形モードでCGGradientを各側に1回使用します。しかし、これが機能するためには、最初に両側に台形のクリッピング領域を設定して、グラデーションがコーナーで留め継ぎされるようにする必要があると思います。

台形領域の作成に使用NSBezierPathするのはかなり簡単で、4つの描画操作を実行するだけで済みます。

左側の台形領域を作成するための基本的なコードは次のとおりです。

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

このようなものも機能する可能性があります。基本的に:クリッピングパスを使用する代わりに、単に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);
于 2009-11-23T16:51:11.033 に答える