【UITableView】選択行から別画面を呼び出す

Posted by: daichi  /  Category: iphone開発

今回はUITableVIewの行をタップした時に別画面を呼び出す
部分を作ります。

行をタップした時にプログラム内部ではUITableViewDelegateで定義されている
tableView:didSelectRowAtIndexPath:メソッドが呼ばれます。

なので、このメソッド内に別画面を呼び出す処理を書いていきます。

学べること

  • Interface Builderの基本的な使い方
  • UITableViewの行選択時の動作
  • navigation Controllerによる画面遷移

前提条件

手順

  1. 新規画面のビュー作成
  2. 新規画面のコントローラ作成
  3. ビューとコントローラの関連づけ
  4. 親画面から新規画面の呼び出し
  5. ビルド

新規画面のビュー作成

行をタップした時に別画面を呼び出す処理を書こうにも
呼び出す画面がなければ書きようがないので、
まずは画面を用意します。

iphoneアプリ開発ではMVCモデルと呼ばれるパターンが使われていますが、
画面はMVCのうちのV、ビューにあたります。

ビューはコードをゴリゴリ書いて作り上げることもできますが、
Interface Builderを使うと見た目を確認しながら感覚的に作ることが
できるので、こちらの方法で作成することにします。

nibファイルの作成

Interface Builderで作成するファイルはnibファイルと呼ばれますが、
まずはこれから作ります。

Xcodeの左のツリーからResoucesを選択した状態で
右クリック→追加→新規ファイルとしてファイル追加ウィンドウを表示します。

新規ビューファイルの追加

新規ファイルとしてVIEW XIBを選択して、次へを押します。

VIEW XIBを選択

ファイル名を入力します。ここではDetailView.xibとします。
次に完了を。

ビューのファイル名を入力

左のツリーのNIBファイルをクリックするとDetailView.xibが作成されているのが確認できます。
次に画面上部のファイルリストからDetailView.xibをダブルクリックして
Inteface Builderを起動します。

起動するとこんなウィンドウが出ます。

DetailView.xibの中身

これがnibファイルの中身で、3つのオブジェクトが
含まれています。

もう一つviewという真っ白なウィンドウが表示されます。

view

これがiPhoneで表示される画面です。
ここにいろんなパーツを追加していきます。

パーツの追加はLibraryから行います。
Libraryはこんなウィンドウです。

library

Libraryの外観は左下の設定ボタンで
アイコンのみを表示など変更ができます。

Libraryが起動していない場合、
上部のメニュー→Tools→Libraryとして起動します。

libraryの起動

あとはオブジェクト同士の接続や、表示設定をするための
Inspectorウィンドウがあります。

connections-inspector

起動していない場合は、
メニュー→Tools→Inspectorとして起動します。

connections inspectoreの起動

今回はこの空っぽのつまらない画面を
表示するのにとどめます。

一度にいろいろやりすぎると
どの操作がどの結果につながっているのかが
わかりにくくなるので。

新規画面のコントローラ作成

というわけで、次にビューに紐づく
コントローラを作成します。

コントローラはモデルとビューとの橋渡し役です。
画面上での操作をコントローラが受けて
モデルへ処理をさせたり、別のビューを表示したり
するのがコントローラの役目です。

左のツリーClassesを選択して
右クリックから→新規→新規ファイル追加として
ファイル追加ウィンドウを表示します。

コントローラの追加

Cocoa Touch Classesの中からUIViewController subclassを選択して次へ。

テンプレートでコントローラを選択

ファイル名はDetailViewController.mとします。
このとき、同時に”DetailViewController.h”も作成にチェックを忘れずに。

detailviewcontrollerの作成

以上でコントローラが作成されましたね。

次にこのコントローラとビューとを紐づけます。

ビューとコントローラの関連づけ

ビュー、コントローラ、それぞれの作成は済みましたが
これらは何の関連もまだ持っていません。

ビューを管理をするコントローラを紐付けます。

File’s Ownerとコントローラの紐付け

まずDetailView.xibウィンドウのFile’s Ownerオブジェクトを選択して

files-ownerを選択

Inspectorウィンドウの一番右のタブIdentityを選択して
一番上のClass Identityプルダウンで先ほど作成したDetailViewControllerを
選択します。

identityでクラス名を指定

これでDetailView.xibの所有者は
DetailViewControllerだという設定がされました。

ビューとFile’s Ownerの紐付け

次はビューとFile’s Ownerを関連づけます。
File’s Ownerを右クリックすると
黒いウィンドウが表示されます。

ビューの紐付け

このウィンドウ内のOutletsの中にviewという項目があるので、
その項目の右の○をドラッグして、viewウィンドウまで
引っ張ってドラッグをはなします。

するとこんな感じでview項目にドラッグ先のviewが紐づきます。

紐付け完了

File’s Ownerとコントローラを紐付け、
File’s Ownerとビューを紐付けたので、
これでコントローラとビューの紐付けが完了しました。

新画面の準備はこれで全部完了です。

Interface Builder上でCommand+Sとして
内容を保存しておきましょう。

親画面から新規画面の呼び出し

編集するファイル

  • RootViewController.m
やっと新画面の準備が終わったので
いよいよ新画面の呼び出し処理を書きます。

冒頭でも説明した通り、UITableViewで選択行をタップすると
tableView:didSelectRowAtIndexPath:メソッドが呼ばれます。

ここに呼び出す処理を書きます。

?View Code OBJECTIVE-C
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:nil];
	[self.navigationController pushViewController:detailViewController animated:YES];
	[detailViewController release];
}


まず先ほど作成したDetailViewControllerのインスタンスを作成します。
[DetailViewController alloc]

作成したインスタンスのinitWithNibName:bundleメソッドを使って初期化します。
initWithName:に指定する名前はビューの名前と同じにする必要があります。
ここではDetailView.xibを作成したので、名前にDetailViewを指定しています。

bundleはひとまずnilで問題ありません。

次に作成したコントローラのインスタンスをnavigationコントローラの
スタックに追加します。

navigationコントローラはスタックに積まれた一番上のコントローラを表示制御
に選択するので、プッシュされたコントローラに対応する画面が表示されます。

最後にプッシュされたDetailViewControllerのインスタンスは
navigationコントローラ内で参照カウンタが1つ増やされるので、
こちらで作成したインスタンスはreleaseして参照カウンタを1つ戻します。

javaやC#といったガベージコレクションをしてくれる
言語を使っていた僕にとってはこのreleaseで参照を解放してしまう
という理屈がはじめ理解できなくてハマりましたが、
最近やっとObjective-Cのメモリの管理方法を理解してきて
分かるようになりました。

参照カウンタ系の話はまた別で書きます。

これだけだと、RootViewController.mはDetailViewControllerという
クラスがどれなのか判断がつかないので、ファイルの頭で
以下のようにDetailViewController.hをimportしておきます。

?View Code OBJECTIVE-C
#import "RootViewController.h"
#import "HelloWorldAppDelegate.h"
#import "DetailViewController.h"
 
@implementation RootViewController


以上でコーディングは終了です。

ビルド

それではビルドしてみましょう。

起動画面はこれまで作成したリストが表示されています。

起動画面

ここで行を選択すると下のような新しい画面が表示されます。

追加画面

でもちょっと待ってください。
さっきは空っぽのビューを用意しただけなのに、
画面上部にナビゲーションバーが表示されていますね。

この部分はnavigationコントローラが作っています。
navigationControllerのスタックに新画面をプッシュしたので、
新画面は始めの画面の小画面だよとnavigationControllerが
認識していて、画面上部に自動的に親画面へ戻るボタンを
表示してくれているわけですね。

同時にいろいろやりすぎるとこのような基本的な
部分の処理がどこで行われているのかが
見えなくなってしまうので今回は
あえて何も表示しないビューを作成しました。

選択行から別画面を呼び出すは以上です。

ちなみにnavigationControllerの
pushViewController:animatedメソッドの
animatedにYESを渡しているので
いかにもiPhoneらしいみよ〜んという
アニメーションで新画面を表示していますが、
animated:NOとするとニヒルにシュッと新画面を
表示できます。

関連のあるアプリ

ipachi2_icon
iPachi 2009/02/10 リリース
ファイナンス 無料
簡易版パチンコパチスロ収支管理アプリ
app_store_badge

タグ: Interface Builder, iPachi, iphone, Navigation Controller, objecti, objective-c, UITableView, UIViewController, Xcode, アイコン, アプリ, チュートリアル, パチスロ, リスト, リリース, 動画, 収支, 画面遷移

関連する投稿

4 Responses to “【UITableView】選択行から別画面を呼び出す”

  1. cessna Says:

    わかりやすい説明で大変参考になっています
    自分なりに応用しようと思ったのですが、いかんせん初心者のため進めなくなりました。教えていただけると助かります

    この記事用に別画面を呼び出し、さらにその画面から別の画面を呼び出したいのですが、どうしても2回目の移動ができません。
    もしかすると仕様で一回のみになっているのかもと思っているのですが、簡単なやりかたを教えていただけると助かります

  2. daichi Says:

    >cessnaさん
    仕様で2回目の移動ができないということはありません。何かしらの不具合があるのだと思います。

    開発を始めたばかりだと一番多いのはメモリリーク関連の不具合でアプリがクラッシュしてしまうことだと思います。

    以前メモリリークやデバッグ関連の記事をまとめたのでこのあたりを参考にしてみてください。

    【iPhone】メモリ不足時のシミュレートとデバッグ | iphoneアプリで稼げるのか

  3. cessna Says:

    こんにちは、コメントありがとうございます
    ようやく解決しましたのでお礼に参りました
    完全に誤解していたのですが、navigationControllerを新たに別のものを設定していたのでうまくいきませんでした。
    メソッドで渡す様にしてやることで2回目の移動もできました。
    もっとスマートなやり方もあるのかもしれませんが。

  4. daichi Says:

    >cessnaさん
    navigationControllerは、initする時にrootControllerとして指定したものを初期表示のコントローラとして、スタックで管理してくれるものなので、コントローラをpushやpopすることで表示中の画面を制御できます。なので、2回目の遷移をしたい時は、初めに用意したnavigationControllerに対して、表示したいコントローラをpushすればいけます。

    navigationControllerを別のものに変えてしまうと、別のスタックでコントローラが管理されてしまうので確かにうまくいかなそうです。

コメント

Get Adobe Flash playerPlugin by wpburn.com wordpress themes