こんにちは、yusuke#9です。
今回はInterface Builderから卒業します。
やっぱりぃ~、IBってぇ~、なんか使いにくいしぃ~
って感じもあるので、ここできっぱりと卒業できるようにしましょう。
作るものは前に作ったボタンでイメージが出たり消えたりするものです。

ではさっそく、プロジェクトを作成。今回は"ButtonActionNoIBSample"としました。
これから、Interface Builderとさよならしましょう。
プロジェクトからMainWindow.xibを消します。
(未練を断ち切るためなので消さなくてもいいです。)
deleteを押して、ゴミ箱に捨ててしまいましょう。

Info.plistからMain nib file base nameの項目を削除。
同じくdeleteで削除できます。
今までは、xibがDelegateの接続をしてくれていたので、
自分で設定をしていかないといけません。
main.mを書き換えます。
UIApplicationMain関数の4番目の引数にDelegateクラス名を指定します。
これで接続ができました。
では、AppDelegateのほうをいじっていきます。
まず、.hを修正します。
image変数の定義を追加します。それと、IBとの接続はなくなったので、
@property宣言は削除します。
(わかりやすいようにコメントアウトしてますが、さくっと消してしまってOKです)
.mのほうにいろいろ追加していきます。
画像を使うので、画像ファイルをプロジェクトに組み込んでおいてください。
今回はIBがやってくれてたことを自分でやるので、結構ボリュームあります。
まず、@synthesizeは@propertyを消したので削除します。
続けて、btnTouchメソッドの実装をします。
処理の内容は前回と同じなのですが、面倒なので簡単に書いてしまいました。
これでメソッドが呼び出されるたびに表示状態が逆になります。
そして、applicationメソッドの中で必要なものを配置していかなくては
いけません。
まず、ウインドウがないので、ウインドウを作ります。
作ったら背景色を白にします。
次に画像を読み込みます。
プロジェクト内に組み込まれているファイルのパスを取得するには
で取得します。
画像パスが取得したら、そのパスを元にUIImageクラスを生成して、ファイルから
画像データを読み込みます。
その後、画像データを元にUIImageViewクラスを生成して、windowに追加します。
これで画像が表示されます。
続けて、ボタンを作ります。
で角の丸いボタンのオブジェクトが生成されます。
frameは大きさと座標を持つプロパティですので、大きさを設定します。
ここで座標を指定してしまってもよいのですが、大きさをきめてからcenterで座標設定
のほうがわかりやすくて好きです。この辺は自分でも気分で使い分けてる感じですかね。。
それから、ボタンにタイトル"Button"を付けます。
そして、イベントを取得できるように設定します。
これで、タッチされたときに、self(AppDelegateクラス自身)のbtnTouchメソッドを呼ぶように
設定できます。@selector(メソッド名)とすると、メソッドを変数として持つことが
できます。引数がある場合はメソッド名のあとに":"を付ける必要があります。
あとは、画像と同じくwindowに組み込んで完成です。
最後に、windowのプロパティ宣言を削除してしまったため、self.windowで
アクセスできなくなっていますので、"self"を取ってしまいます。
これでコードはできました。ビルドと実行をしてみましょう。

ちゃんと動きましたか?
これで完成です!
IBを使わないで全て解決できるのか、というとまだちょっとわからないです。
今後いろいろやっていくうちに見えてくるかもしれないです。
それに、IBのが感覚的で使いやすい部分もあるし、インターフェースの構造とかでは
IBでやったほうが処理がスムーズかも、とかあると思うので、
うまく使い分けしていければいいですね。
サンプルはこちら
http://yupj.jp/ameblo-binary/101230/ButtonActionNoIBSample.zip
今回はInterface Builderから卒業します。
やっぱりぃ~、IBってぇ~、なんか使いにくいしぃ~
って感じもあるので、ここできっぱりと卒業できるようにしましょう。
作るものは前に作ったボタンでイメージが出たり消えたりするものです。

ではさっそく、プロジェクトを作成。今回は"ButtonActionNoIBSample"としました。
これから、Interface Builderとさよならしましょう。
プロジェクトからMainWindow.xibを消します。
(未練を断ち切るためなので消さなくてもいいです。)
deleteを押して、ゴミ箱に捨ててしまいましょう。

Info.plistからMain nib file base nameの項目を削除。
同じくdeleteで削除できます。
今までは、xibがDelegateの接続をしてくれていたので、
自分で設定をしていかないといけません。
main.mを書き換えます。
UIApplicationMain関数の4番目の引数にDelegateクラス名を指定します。
int retVal = UIApplicationMain(argc, argv, nil, @"ButtonActionNoIBSampleAppDelegate");
これで接続ができました。
では、AppDelegateのほうをいじっていきます。
まず、.hを修正します。
@interface ButtonActionNoIBSampleAppDelegate : NSObject{
UIWindow *window;
UIImageView *image; // 追加
}
// 削除 @property (nonatomic, retain) IBOutlet UIWindow *window;
@end
image変数の定義を追加します。それと、IBとの接続はなくなったので、
@property宣言は削除します。
(わかりやすいようにコメントアウトしてますが、さくっと消してしまってOKです)
.mのほうにいろいろ追加していきます。
画像を使うので、画像ファイルをプロジェクトに組み込んでおいてください。
@implementation ButtonActionNoIBSampleAppDelegate
// 削除 @synthesize window;
// メソッド定義追加
- (void)btnTouch:(id)sender{
image.hidden =! image.hidden;
}
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// ここから
// ウインドウを作る
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
window.backgroundColor = [UIColor whiteColor];
// 画像の読み込み
NSString *path = [[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"];
UIImage* img = [[UIImage alloc] initWithContentsOfFile:path];
image = [[UIImageView alloc] initWithImage:[img autorelease]];
[window addSubview:image];
image.center = CGPointMake(160, 180);
// ボタンの組み込み
UIButton* btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 100, 40);
[btn setTitle:@"Button" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnTouch:) forControlEvents:UIControlEventTouchDown];
[window addSubview:btn];
btn.center = CGPointMake(160, 350);
// ここまで
// [self.window makeKeyAndVisible];
[window makeKeyAndVisible]; // 書き換え
return YES;
}
今回はIBがやってくれてたことを自分でやるので、結構ボリュームあります。
まず、@synthesizeは@propertyを消したので削除します。
続けて、btnTouchメソッドの実装をします。
処理の内容は前回と同じなのですが、面倒なので簡単に書いてしまいました。
これでメソッドが呼び出されるたびに表示状態が逆になります。
そして、applicationメソッドの中で必要なものを配置していかなくては
いけません。
まず、ウインドウがないので、ウインドウを作ります。
作ったら背景色を白にします。
次に画像を読み込みます。
プロジェクト内に組み込まれているファイルのパスを取得するには
[[NSBundle mainBundle] pathForResource:@"ファイル名(拡張子なし)" ofType:@"拡張子"]
で取得します。
画像パスが取得したら、そのパスを元にUIImageクラスを生成して、ファイルから
画像データを読み込みます。
その後、画像データを元にUIImageViewクラスを生成して、windowに追加します。
これで画像が表示されます。
続けて、ボタンを作ります。
UIButton* btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
で角の丸いボタンのオブジェクトが生成されます。
frameは大きさと座標を持つプロパティですので、大きさを設定します。
ここで座標を指定してしまってもよいのですが、大きさをきめてからcenterで座標設定
のほうがわかりやすくて好きです。この辺は自分でも気分で使い分けてる感じですかね。。
それから、ボタンにタイトル"Button"を付けます。
そして、イベントを取得できるように設定します。
[btn addTarget:self action:@selector(メソッド名:) forControlEvents:UIControlEventTouchDown];
これで、タッチされたときに、self(AppDelegateクラス自身)のbtnTouchメソッドを呼ぶように
設定できます。@selector(メソッド名)とすると、メソッドを変数として持つことが
できます。引数がある場合はメソッド名のあとに":"を付ける必要があります。
あとは、画像と同じくwindowに組み込んで完成です。
最後に、windowのプロパティ宣言を削除してしまったため、self.windowで
アクセスできなくなっていますので、"self"を取ってしまいます。
これでコードはできました。ビルドと実行をしてみましょう。

ちゃんと動きましたか?
これで完成です!
IBを使わないで全て解決できるのか、というとまだちょっとわからないです。
今後いろいろやっていくうちに見えてくるかもしれないです。
それに、IBのが感覚的で使いやすい部分もあるし、インターフェースの構造とかでは
IBでやったほうが処理がスムーズかも、とかあると思うので、
うまく使い分けしていければいいですね。
サンプルはこちら
http://yupj.jp/ameblo-binary/101230/ButtonActionNoIBSample.zip