1

iOS アプリのボタンに赤いグラデーションを付けたいです。最初はこれを行うために画像を使用していましたが、QuartzCore フレームワークでそれを行うことができることに気付きました。次の実装ファイルがあります。

#import "RedButton.h"

@implementation RedButton

@synthesize gradientLayer = _gradientLAyer;

- (void)awakeFromNib;
{
    // Initialize the gradient layer
    self.gradientLayer = [[CAGradientLayer alloc] init];
    // Set its bounds to be the same of its parent
    [self.gradientLayer setBounds:[self bounds]];
    // Center the layer inside the parent layer
    [self.gradientLayer setPosition:
     CGPointMake([self bounds].size.width/2,
                 [self bounds].size.height/2)];

    // Insert the layer at position zero to make sure the 
    // text of the button is not obscured
    [[self layer] insertSublayer:self.gradientLayer atIndex:0];

    // Set the layer's corner radius
    [[self layer] setCornerRadius:5.0f];
    // Turn on masking
    [[self layer] setMasksToBounds:YES];
    // Display a border around the button 
    // with a 1.0 pixel width
    [[self layer] setBorderColor:[UIColor colorWithRed:(158.0f/255.0f) green:0.0f blue:0.0f alpha:1.0f].CGColor];
    [[self layer] setBorderWidth:1.0f];

    [self.gradientLayer setColors:[NSArray arrayWithObjects:
                               (id)[[UIColor colorWithRed:(214.0f/255.0f) green:0.0f blue:0.0f alpha:1.0f] CGColor], 
                               (id)[[UIColor colorWithRed:(141.0f/255.0f) green:0.0f blue:0.0f alpha:1.0f] CGColor], nil]];

    [[self layer] setNeedsDisplay];

}

- (void)drawRect:(CGRect)rect;
{
    [super drawRect:rect];
}

- (void)dealloc {
    // Release our gradient layer
    self.gradientLayer = nil;
    [super dealloc];
}
@end

最初の質問 - ここで awakeFromNib を使用してもよろしいですか? または、initWithFrame を使用する必要がありますか?

2 番目の質問 - もともと私は画像を使用し、インターフェイス ビルダーを使用して、ボタンのデフォルトおよび強調表示された状態を設定していました。画像を使用していないので、強調表示されたときにボタンの外観を変更するにはどうすればよいですか? グラデーションを逆にしたいだけです。

3 番目の質問 - UIButton をサブクラス化してはいけないと書かれているのを見たことがあります。そうでない場合、多くのコードを複製せずに、すべてのボタンをこのグラデーションに変更するにはどうすればよいでしょうか?

前もって感謝します。

4

1 に答える 1

3

edit1:画像に関する部分を読み違えました。グラデーションを使用してボタンの状態を画像としてネイティブに設定するには、このようなことができるはずです

// your code for setting up the gradient layer comes first
UIGraphicsBeginImageContext(CGSizeMake(1, [self bounds].size.height));
[gradientLayer renderInContext: UIGraphicsGetCurrentContext()];
UIImage *bgImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackGroundImage:bgImage forState:UIControlStateWhatever] // replace with correct states

============================

初期化コードを以外の関数に入れることをお勧めしますawakeFromNib(ボタンが実際にはペン先で使用されていないが、コードで作成されている可能性がある場合)。initWithCoderカスタム初期化関数を作成し、両方で呼び出す必要があります。initWithFrame この回答は、そうするためのかなり良いパターンを示しています。

を呼び出して、初期化のさまざまな状態の背景を設定できます。

[self setBackGroundImage: forState];

この場合、あなたの州は になりますUIControlStateHighlighted

それはさておき、この状況でのサブクラス化に対する 1 つの議論は、カスタム動作を実際に定義しているのではなく、スタイリング コードを再利用しようとしているだけだということです。ここではサブクラスは必要ありません。シナリオとして UIButton を受け取り、その初期化コードをすべて実行する書式設定関数をどこか (おそらくビューコントローラー、または別のクラスの関数) に作成するだけの簡単なことを行うことができます。このようにして、ボタンがサブクラスに閉じ込められることはありません (これは、実際に別の UIButton サブクラスを使用することになった場合に便利です。たとえば、カスタム タッチ動作を定義するものを使用して、ボタンを非四角形にすることができます。形状(およびそのタッチ領域がそのように制限されています)。

私が見た別の議論は、UIButton には、サブクラスとは異なるタイプのボタンを返す可能性のあるファクトリ関数が含まれていますが、それらの関数を使用しない場合、この問題に遭遇することはないというものです。

于 2012-06-25T14:46:15.703 に答える