2

UILabels (または必要に応じて UILabel を上に置く UIView) のより洗練された描画を作成しようとしています。ユーザーがiPhoneの向きを変更したときにこれを自動的にサイズ変更したいので、これをサブクラスのdrawRect関数に実装しようとしています。可能であれば、パターン イメージの必要性を省略して、これをすべてコードで調整できるようにしたいと考えています。

この件に関する以前の投稿からいくつかのヒントを得ました。

iPhone の UIView と UILabels のグラデーションと UIView の背景をサブクラス化なしのグラデーションにする

残念ながら、グラデーションとカスタム描画を組み合わせたかったので、どちらも目標を達成できませんでした。CGGradient を描画中の線枠 (丸みを帯びた角に表示されます) でクリップしたいのですが、これを達成できません。

別の方法は、CAGradientLayer を使用することです。これは非常にうまく機能しているように見えますが、回転時にフレームのサイズを変更する必要があり、どのように試しても、グラデーション レイヤーがテキストの上に描画されているように見えます。

そのための私の質問は2つあります

  • 以下のコードを変更して、描画された「フレーム」にグラデーション クリップを作成するにはどうすればよいですか
  • CAGradientLayer を UILabel のテキストの後ろに描画するにはどうすればよいですか (または、CAGradientLayer を背景として UILabel の後ろに UIView を配置する必要がありますか)

これが私の drawrect 関数です:

- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [[UIColor clearColor] CGColor]);
CGContextSetStrokeColorWithColor(c, [strokeColor CGColor]);
CGContextSetLineWidth(c, 1);

CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;

maxx = maxx - 1;
maxy = maxy - 1;

CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 0.6, 0.6, 0.6, 1.0,  // Start color
0.3, 0.3, 0.3, 1.0 }; // End color

rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

CGRect currentBounds = [self bounds];
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds),            CGRectGetMidY(currentBounds));
CGPoint lowCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));

CGContextDrawLinearGradient(c, glossGradient, topCenter, midCenter, 0);

CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace); 

CGContextMoveToPoint(c, minx, midy);
CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE_INFO);
CGContextAddArcToPoint(c, maxx, miny, maxx, midy, ROUND_SIZE_INFO);
CGContextAddArcToPoint(c, maxx, maxy, midx, maxy, ROUND_SIZE_INFO);
CGContextAddArcToPoint(c, minx, maxy, minx, midy, ROUND_SIZE_INFO);

// Close the path
CGContextClosePath(c);
// Fill & stroke the path
CGContextDrawPath(c, kCGPathFillStroke);                
//        return;  

[super drawRect: rect]; 
4

1 に答える 1

3

あなたが探しているのは CGContextClip() です

コードのようにパスとグラデーションを作成し、次に

CGContextClip(c);
CGContextDrawLinearGradient(c, glossGradient, topCenter, midCenter, 0);
CGGradientRelease(glossGradient);

(CGContextDrawLinearGradient への古い呼び出しを削除します)

また、クリッピングを行う前後に、コンテキストを保存して復元することを忘れないでください

クリッピングが必要なものとは逆になっている場合は、CGContextEOClip() を試してください (または逆の順序でパスを描画します)。

于 2010-10-24T16:44:37.200 に答える