iOS で画像を使わずに角丸ボタンを作ってみました。
UIButton でボタンを描画する方法
UIButton でボタンを描画する場合は drawRectメソッドを利用します。
- (void)drawRect:(CGRect)rect {
// ここに記述
[super drawRect:rect];
}
グラデーションカラーの角丸ボタンを作成
こんな感じのを作ってみたいと思います。

CustomButton.m を作成
とりあえず、CustomButton.m を作成して、drawRect の中身にグラデーションカラーの角丸ボタンの記述を追加してみました。
CustomButton.m
@interface CustomButton : UIButton
@end
@implementation CustomButton
-(id)initWithFrame:(CGRect)frame {
if ([super initWithFrame:frame]) {
self.titleLabel.font = [UIFont boldSystemFontOfSize:12];
self.titleLabel.shadowOffset = CGSizeMake(0.0, 1.0);
[self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[self setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
[self setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
}
return self;
}
-(void)setHighlighted:(BOOL)value {
[super setHighlighted:value];
[self setNeedsDisplay];
}
-(void)setSelected:(BOOL)value {
[super setSelected:value];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
CGContextRef c = UIGraphicsGetCurrentContext();
CGFloat w = self.bounds.size.width;
CGFloat h = self.bounds.size.height;
CGFloat r = h/2;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextSaveGState(c);
CGContextSetShouldAntialias(c, true);
// 角丸の描画領域を設定
CGRect rc = CGRectMake(0, 0, w, h);
CGContextMoveToPoint(c, CGRectGetMinX(rc), CGRectGetMaxY(rc)-r);
CGContextAddArcToPoint(c, CGRectGetMinX(rc), CGRectGetMinY(rc), CGRectGetMidX(rc), CGRectGetMinY(rc), r);
CGContextAddArcToPoint(c, CGRectGetMaxX(rc), CGRectGetMinY(rc), CGRectGetMaxX(rc), CGRectGetMidY(rc), r);
CGContextAddArcToPoint(c, CGRectGetMaxX(rc), CGRectGetMaxY(rc), CGRectGetMidX(rc), CGRectGetMaxY(rc), r);
CGContextAddArcToPoint(c, CGRectGetMinX(rc), CGRectGetMaxY(rc), CGRectGetMinX(rc), CGRectGetMidY(rc), r);
CGContextClip(c);
// CGGradientを生成する
// 生成するためにCGColorSpaceと色データの配列が必要になるので適当に用意する
CGFloat locations[2] = {0.0, 1.0};
size_t num_locations = 2;
CGGradientRef gradient;
if (self.state && (UIControlStateSelected || UIControlStateHighlighted)) {
CGFloat components[8] = {0.85, 0.85, 0.85, 1.0, 0.68, 0.68, 0.68, 1.0};
gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, num_locations);
} else {
CGFloat components[8] = {0.9, 0.9, 0.9, 1.0, 0.73, 0.73, 0.73, 1.0};
gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, num_locations);
}
// 生成したCGGradientを描画する
// 始点と終点を指定してやると、その間に直線的なグラデーションが描画される。
CGPoint startPoint = CGPointMake(w/2, 0.0);
CGPoint endPoint = CGPointMake(w/2, h);
CGContextDrawLinearGradient(c, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(c);
[super drawRect:rect];
}
@end
メインから CustomButton を呼び出す
上記で作った CustomButton をメインから呼び出したら、なぜか drawRect が呼ばれなかった。
なぜだ!? と思ってたら、ボタンを生成するときに buttonWithType の値を UIButtonTypeCustom にしないとダメみたい。なるほど…。
×
CustomButton *btn = [[CustomButton buttonWithType:UIButtonTypeRoundedRect] retain];
○
CustomButton *btn = [[CustomButton buttonWithType:UIButtonTypeCustom] retain];
カスタムボタンの追加はこんな感じ。
CustomButton *btn; btn = [[CustomButton buttonWithType:UIButtonTypeCustom] retain]; [btn setTitle:@"Click..." forState:UIControlStateNormal]; CGSize size = [btn.titleLabel.text sizeWithFont:btn.titleLabel.font forWidth:4000 lineBreakMode:UILineBreakModeTailTruncation]; btn.frame = CGRectMake(20.0f, 20.0f, size.width + 20.0f, size.height + 10.0f); [btn addTarget:self action:@selector(didTouchUp:) forControlEvents:UIControlEventTouchUpInside]; [btn release];
