Bezelボタンを作る[01]Round Rect を描く

2010年6月15日火曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Bezel

Bezel とはこんなやつ。
くぼんでいるように見える表現で、大抵は左上から光が当たっているのを仮定して、左と上側に影が落ちているような表現になっている。最終的にはボタンとして機能するようにする。

まずは、これを iPhone で描いてみよう。
iPhone 上でのグラフィック描画には Quartz 2D のCG系関数を使う。
CGContext Reference

描くにあたって次のステップで進めてみた。

  1. 角丸矩形(RoundRect)を描く
  2. 影を描く
  3. 矩形の内側に影を落とす
順番にやっていく。

角丸矩形(RoundRect)を描く

Mac OS X だと NSBezierPath を使い簡単に角丸矩形が描けるが、iPhoneの場合はこれが使えない。実は iPhone OS 3.2 からだと UIBezierPath が用意されたので代わりにこれが使える。ただ今回は OS 3.1.3 向けに作りたいので、自前で描くことにする。

UIBezierPath Class Reference

ネットで調べてみると CALayer を使う方法と自前で描く方法の2種類があった。今回は UIView へ直接描画するので後者の方法をとることにした。これは角丸の部分を CGContextAddArcToPoint() を使い一つ一つ描いていく。コードはこんな感じ。
- (void)addRoundRectPath:(CGContextRef)context rect:(CGRect)rect
{
 // Top Left
 CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + CORNER_RADIUS);
 CGContextAddArcToPoint(context,
         rect.origin.x,
         rect.origin.y,
         rect.origin.x + CORNER_RADIUS,
         rect.origin.y,
         CORNER_RADIUS);
 // Top right
 CGContextAddArcToPoint(context,
         rect.origin.x + rect.size.width,
         rect.origin.y,
         rect.origin.x + rect.size.width,
         rect.origin.y + CORNER_RADIUS,
         CORNER_RADIUS);
 // Bottom right
 CGContextAddArcToPoint(context,
         rect.origin.x + rect.size.width,
         rect.origin.y + rect.size.height,
         rect.origin.x + rect.size.width - CORNER_RADIUS,
         rect.origin.y + rect.size.height,
         CORNER_RADIUS);
 // Bottom left
 CGContextAddArcToPoint(context,
         rect.origin.x,
         rect.origin.y + rect.size.height,
         rect.origin.x,
         rect.origin.y,
         CORNER_RADIUS);

 CGContextClosePath(context);
} 
面倒だが複雑ではない。四辺と四つの角丸(arc)を一つづつ繋げているだけ。

参考サイト:Drawing a round rect with Quartz « dPompa

このメソッドでパスを描いた後、CGContextFillPath() などで色を塗れば良い。
- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor whiteColor] set];
    [self addRoundRectPath:context rect:rect];
    CGContextFillPath(context);
}

実行例

Responses

Leave a Response

人気の投稿(過去 30日間)