Viewにグラデーションレイヤを適用する
androidではGUI部品に対して色のグラデーションを描画する場合、XMLでDrawableのインスタンスを記述するか、コードにより直接GradientDrawableクラスのインスタンスを生成するコードを書き、対象のViewに適用することで可能だった。
androidによるグラデーションの描画
- XMLによるグラデーションシェイプ記述
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#ffff0000" android:endColor="#ff0000ff" android:angle="270" /> </shape>
- コードによるGradientDrawableクラスの生成
GradientDrawable gradient = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]{0xffff0000, 0x0000ff}); view.setBackgroundDrawable(gradient);
- 表示結果
iOSによるグラデーションの描画(UIViewController)
一方iOSだがandroidのようにXMLで記述することはできないので、もっぱらコードで記述することになる。
iOSはViewにレイヤを追加することができるのだが、グラデーションのためにCAGradientLayerというクラスがQuartzCoreに用意されているので、これを使う。
- UIViewController.viewDidLoad
#import <QuartzCore/QuartzCore.h> - (void)viewDidLoad { [super viewDidLoad]; 〜 CAGradientLayer* gradient = [CAGradientLayer layer]; gradient.frame = self.view.bounds; gradient.colors = [NSArray arrayWithObjects: (id)[[UIColor redColor] CGColor], //開始色 (id)[[UIColor blueColor] CGColor], //終了色 nil]; [gradient setStartPoint:CGPointMake(0.5, 0.0)]; [gradient setEndPoint:CGPointMake(0.5, 1.0)]; // 0 degree [self.view.layer insertSublayer:gradient atIndex:0]; }
プロパティStartPointとEndPointはグラデーションの開始座標と終了座標を指定する。CALayerの場合、原座標はデフォルトでは左端上が(0, 0)、右端下が(1,1)に設定されており、その中の二点の座標を指定することでグラデーションの開始と終了点を指定する。
androidのDrawableで設定するAngle(角度)と対応させるとそれぞれ
-
- 0°
StartPoint = (0.5, 0.0) EndPoint = (0.5, 1.0)
-
- 45°
StartPoint = (1.0, 0.0) EndPoint = (0.0, 1.0)
-
- 90°
StartPoint = (1.0, 0.5) EndPoint = (0.0, 0.5)
:
:
という対応になる。
- 表示結果
このようにUIViewControllerで簡単にグラデーションレイヤを追加できるのは素晴らしいのだが、この方法には問題がある。
このようにビューがローテート等でリサイズした場合にレイヤが再描画されないのである。
やはりアドホックな対応というのは無理があるようだ。さて、どうしようか。
※本題とは違うが、赤から青へのグラデーションというのは美しいものだ。