2010/02/05

[Objective-C][iPhone sdk]UIViewControllerとUIButtonとaddTargetの3角関係

ちょっと前にこの本を買いました。

サンプルコードを模写しているのですが、その中でちょっと苦戦してしまったことが。。。

UIButtonを使ってアクションを起こすプログラムが紹介されていたのですが、InterfaceBuilderが使われていて、よくわからなかったのでネイティブに実装することに。

//ViewController.h
@interface ViewController : UIViewController {

}

@end

//ViewController.m
#import "ViewController.h"

@implementation ViewController

- (void)loadView {
MainView *mainview = [[MainView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = mainview;
UIButton *mainbutton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
mainbutton.frame = CGRectMake(50, 50, 100, 50);
[mainbutton setTitle:@"Tap" forState:UIControlStateNormal];
mainbutton.backgroundColor = [UIColor clearColor];
[mainbutton addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:mainbutton];
[mainview release];
}

-(void)play:(id)sender{
NSLog(@"ボタンが押されました\n");
}

これを実行するとボタンの表示はできたのですが、ボタンを押すとiPhoneがクラッシュします。

で、クラッシュする理由を調べたのですが、ひょっとしたらplayメソッドの位置がおかしいのかなーっと思い、UIViewのサブクラスにUIButtonのselectorメソッドを置きました。

こんな感じ。
//ViewController.h
#import "MainView.h"

@interface ViewController : UIViewController {

}

@end

//ViewController.m
- (void)loadView {
MainView *mainview = [[MainView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = mainview;
[mainview release];
}

//MainView.h
@interface MainView : UIView {

}

@end

//MainView.m
#import "MainView.h"

@implementation MainView


- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}

UIButton *mainbutton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
mainbutton.frame = CGRectMake(50, 50, 100, 50);
[mainbutton setTitle:@"Tap" forState:UIControlStateNormal];
mainbutton.backgroundColor = [UIColor clearColor];
[mainbutton addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:mainbutton];
return self;
}

-(void)play:(id)sender{
NSLog(@"ボタンが押されました\n");
}

これを実行したらNSLogがきちんと実行されました。

ものすごく奇妙なのがUITableViewControllerの場合は、selectorのメソッドをControllerファイル内で実装してもクラッシュしないのにその親クラスであるUIViewControllerではダメなんて。

う〜ん、奥深いなー。

0 コメント:

コメントを投稿