iOSでUIButtonの選択時の背景色をグラデーションにする
移転しました →
UIButtonの背景色をグラデーションにする方法は簡単です。適当にググればでてきますし。ですが、ボタンをタップしたときの色をグラデーションにする方法はちょっと面倒でトリッキーだったので紹介します。
その前に、背景色を普通にグラデーションにする方法はこちら。
Objective-C - UIButton をグラデーションにする - Qiita [キータ]
UIButtonのサブクラスを作る
オリジナルのButton用クラスを用意しておくと便利です。
// GradientButton.h @interface GradientButton : UIButton @end
// GradientButton.m #import "GradientButton.h" @implementation GradientButton - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; [self setupBackgroundGradientForState:UIControlStateNormal colors:@[(id)[[UIColor cyanColor] CGColor], (id)[[UIColor greenColor] CGColor]]]; [self setupBackgroundGradientForState:UIControlStateHighlighted colors:@[(id)[[UIColor magentaColor] CGColor], (id)[[UIColor redColor] CGColor]]]; return self; } - (void)setupBackgroundGradientForState:(NSUInteger)state colors:(NSArray*)colors { CAGradientLayer *gradient = [[CAGradientLayer alloc] init]; gradient.frame = self.bounds; gradient.colors = colors; UIGraphicsBeginImageContext(CGSizeMake(1, [self bounds].size.height)); [gradient renderInContext: UIGraphicsGetCurrentContext()]; UIImage *bgImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [self setBackgroundImage:bgImage forState:state]; }
基本的にはUIViewの背景色をグラデーションにするときと同じく、CAGradientLayer
を用いてグラデーションを設定します。凝ったグラデーションを作る場合はCAGradientLayer
でいろいろやっている人を探せば見つかると思うので丸投げです。
で、今回の肝なんですが、作ったCAGradientLayer
をaddSubLayer
するのではなく、CAGradientLayer
からUIImage
を生成して背景画像に設定してしまうという方法をとっています。背景画像の設定のときにUIControlState
を渡すのでUIControlStateHighlightedを渡してあげれば、タップ時の背景画像をグラデーションにするという目的を果たすことができます。
ストーリーボードやXIBを使っている場合には、配置したUIButtonのカスタムクラスをこのGradientButton
クラスにしてあげれば良いです。
結果
タップがわかりづらいかもですが、ちゃんとタップ時の色をグラデーションにできていると思います。
余談:ハイライト時のエフェクトを無くす
上のGIF画像を見ると、タップしたときの背景色が指定したものよりも薄いことがわかると思います。これはデフォルトでつけられているエフェクトによってぼんやりと薄くなってしまっているわけですね。
せっかく背景色をグラデーションにカスタマイズしたのに勝手にエフェクト掛けられたら困ると思い、エフェクトを消す方法をstackoverflowあたりでググって見ると、インスペクタでHighlighted Adjusts Image
をオフにする、またはコードで
button.adjustsImageWhenHighlighted = NO;
のようにすればいいよ、ということでした。
ですが、それは効かず!
結局ボタンタイプをSystem
からCustom
にすればエフェクトはなくなりました。
設定後のグラデーションの様子はこちら。タップ時の色が濃くなったのがわかると思います。