UIButtonを動的に作る
iPhoneアプリを作りたいなーと思って、少し前から図書館で本を借りたりしながら勉強しているのだけど、どうもInterfaceBuilderの使い方がよく分からなくて挫折してしまう。というか図書館で借りてきた本のキャプチャ画像と実際の画面が違ってたりすると、自分でもびっくりするくらい簡単に混乱して諦めてしまってた。
そこで、とりあえずInterfaceBuilderを使うのはやめて、UI周りもコードでごりごり書こうかと思った。そうすることで、iPhoneアプリに必要な部分がコードとして可視化されて理解も深まるだろうと、ついでにInterfaceBuilderが何をしているのかが分かるようになるかなと。
とりあえず、今日はボタンを動的に作ってみたのでメモ。
とりあえず生成、UIButton の buttonWithType: でインスタンスを生成してその後でそれぞれのプロパティを設定する。
+ (id)buttonWithType:(UIButtonType)buttonType
UIButtonTypeは以下のものを指定できる。
UIButtonTypeCustom | 画像ボタン |
---|---|
UIButtonTypeRoundedRect | 普通のボタン |
UIButtonTypeDetailDisclosure | (>)ボタン |
UIButtonTypeInfoLight | (i)白ボタン |
UIButtonTypeInfoDark | (i)黒ボタン |
UIButtonTypeContactAdd | (+)ボタン |
UIView から継承されている tag プロパティには数字をセットできて、同じようなボタンを大量に作ったときにどのボタンかを識別するのに使える。
簡単な生成コードは以下
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = frame; // CGRect: UIViewのインスタンスメソッド button.tag = tag; // NSInteger: UIViewのインスタンスメソッド [button setTitle:title forState:UIControlStateNormal]; // UIButtonのインスタンスメソッド [view addSubview:button]; // viewはボタンを貼付けるUIViewのインスタンス
ボタンなんで押したときに何か反応してほしい、それには UIControl の addTarget:action:forControlEvents を使う。
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
UIControlEventsは以下のように定義されている。動作の詳細はよく分からないけど、だいたい名前で判断できる。あと、ビットシフトで定義されているので複数のイベントをまとめて登録するとかもできそう。
enum { UIControlEventTouchDown = 1 << 0, UIControlEventTouchDownRepeat = 1 << 1, UIControlEventTouchDragInside = 1 << 2, UIControlEventTouchDragOutside = 1 << 3, UIControlEventTouchDragEnter = 1 << 4, UIControlEventTouchDragExit = 1 << 5, UIControlEventTouchUpInside = 1 << 6, UIControlEventTouchUpOutside = 1 << 7, UIControlEventTouchCancel = 1 << 8, UIControlEventValueChanged = 1 << 12, UIControlEventEditingDidBegin = 1 << 16, UIControlEventEditingChanged = 1 << 17, UIControlEventEditingDidEnd = 1 << 18, UIControlEventEditingDidEndOnExit = 1 << 19, UIControlEventAllTouchEvents = 0x00000FFF, UIControlEventAllEditingEvents = 0x000F0000, UIControlEventApplicationReserved = 0x0F000000, UIControlEventSystemReserved = 0xF0000000, UIControlEventAllEvents = 0xFFFFFFFF };
サンプルプログラム
それらを踏まえて、ボタンを押したら数字が増える数字入力機能のみの電卓(?)プログラムを書いてみた。
#import <UIKit/UIKit.h> #define KEY_CLEAR -1 #define KEY_BACK -2 #define MAX_VALUE 10000000 @interface NumberController : UIViewController { int num; UILabel *label; } @end @implementation NumberController // ボタンを押したときに呼ばれる // どのボタンを押したかは [sender tag] で取得する -(void)pushed_button: (id)sender { if ([sender tag] == KEY_CLEAR) { num = 0; } else if ([sender tag] == KEY_BACK) { num /= 10; } else if (num < MAX_VALUE) { num *= 10; num += [sender tag]; } label.text = [NSString stringWithFormat:@"%d", num]; } -(CGRect)getFrameWithCol:(int)col row:(int)row { return CGRectMake(100 * col + 15, 40 * row + 90, 90, 32); } -(UIButton*)createButtonWithTitle:(NSString*)title tag:(int)tag frame:(CGRect)frame { UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = frame; button.tag = tag; [button setTitle:title forState:UIControlStateNormal]; [button addTarget:self action:@selector(pushed_button:) forControlEvents:UIControlEventTouchUpInside]; return button; } - (void)loadView { UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; contentView.backgroundColor = [UIColor lightGrayColor]; self.view = contentView; // ラベルの生成 label = [[UILabel alloc] initWithFrame: CGRectMake(10, 20, 300, 55)]; label.text = @"0"; label.textAlignment = UITextAlignmentRight; label.font = [UIFont fontWithName:@"Courier" size:48.0f]; label.textColor = [UIColor blackColor]; label.shadowColor = [UIColor lightGrayColor]; label.shadowOffset = CGSizeMake(2.5f, 2.0f); label.backgroundColor = [UIColor whiteColor]; [contentView addSubview: label]; // 数字ボタンの生成 for (int i = 0; i < 10; i++) { int n = i >= 9 ? 0 : (7 - (i / 3) * 3) + (i % 3); NSString *title = [NSString stringWithFormat:@"%d", n]; CGRect frame = [self getFrameWithCol:(i % 3) row:(i / 3)]; UIButton *button = [self createButtonWithTitle:title tag:n frame:frame]; [contentView addSubview:button]; } // Back, Clearボタンの生成 UIButton *backButton = [self createButtonWithTitle:@"Back" tag:KEY_BACK frame:[self getFrameWithCol:1 row:3]]; UIButton *clearButton = [self createButtonWithTitle:@"Clear" tag:KEY_CLEAR frame:[self getFrameWithCol:2 row:3]]; [contentView addSubview:backButton]; [contentView addSubview:clearButton]; [contentView release]; } - (void)dealloc { [label release]; [super dealloc]; } @end @interface TestDelegate : NSObject<UIApplicationDelegate> @end @implementation TestDelegate - (void)applicationDidFinishLaunching: (UIApplication*)application { UIWindow *window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]]; UIViewController *vc = [[NumberController alloc] init]; [window addSubview: vc.view]; [window makeKeyAndVisible]; } - (void)dealloc { [super dealloc]; } @end int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"TestDelegate"); [pool release]; return retVal; }