2011年12月13日火曜日

Storyboardで画面遷移を作る (iOS)

Xcode4.2からStoryboadというものが使えるようになりました。いままで画面ごとにnibファイルを作ってプログラムで画面遷移することができましたが、Storyboardを使えば各画面の関係を1画面で見渡すことができます。また、単純な画面遷移ならプログラムを一切書かずに作ることができます。

最も簡単な画面遷移

ボタンを押したら次の画面に移動するだけの簡単な画面遷移を作ってみます。

まずはプロジェクトの作成から。

File –> New –> New Project でSingle View Applicationを選択します。
新規プロジェクトのプロジェクト名などを入力する画面で「Use Storyboard」のチェックを入れて、プロジェクトを作成します。

次に、Navigation Controllerを追加します。

Navigation Controllerをドラッグしてキャンバスに置きます。NavigationControllerとルートビューが画面に出てきます。

Attribute inspectorでNavigationControllerのIs Initial View Controllerをチェックします。

画面遷移を作ります。

ルートビューにボタンを配置します。Ctrlキーを押しながらボタンをドラッグして最初からあるView Controllerに線を引きます。Storyboard Seguesのポップアップが出ます。ここはNavigationControllerによる画面遷移なのでpushを選びます。

お好みでナビゲーションバーにタイトルを付けたり、2番目の画面にラベルを付けたりします。

Runボタンで実行します。最初の画面のボタンを押すと次の画面へ遷移します。2番目の画面のナビゲーションバーには戻るボタンが表示され、最初の画面に戻ることができます。

プログラムによる画面遷移

ボタンのアクションとしての画面遷移はマウスで線を引くだけで設定できましたが、イベントなどプログラムの任意のタイミングで画面遷移したいこともあります。このようなときはプログラムで画面遷移を呼び出すことができます。

先ほどのアプリに新しい画面を追加して、スワイプしたら画面遷移するようにしてみます。

新しい画面を追加します。StoryboardのキャンバスにView Controllerをドラッグします。

初期画面のViewから新しく追加したViewにCtrlキーを押しながらドラッグしてSegueを作成します。Styleはもちろんpushです。このSegueのIdentifierを設定します(ここでは”konnichiwa”としました)。

初期画面のIdentity inspectorでViewControllerのサブクラスを割り当てます。新規に作ってもいいのですが、ここではプロジェクト作成時に自動的に作られたViewControllerをそのまま使いました(HWViewController)。

HWViewControllerにジェスチャを認識するためにUISwipeGestureRecognizerを追加します。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
   
    swipe = [[UISwipeGestureRecognizer alloc]
        initWithTarget:self action:@selector(handleSwipeGesture:)];
    swipe.direction = UISwipeGestureRecognizerDirectionLeft;
    swipe.numberOfTouchesRequired = 1;
    [self.view addGestureRecognizer:swipe];

}

- (void)viewWillDisappear:(BOOL)animated
{
   
    [self.view removeGestureRecognizer:swipe];
    swipe = nil;
   
    [super viewWillDisappear:animated];
   
}

スワイプされたときのハンドラを作成します。

self(つまりViewController)のperformSegueWithIdentifier:sender:で先ほど”konnichiwa”というIdentifierを付けたSegueを実行します。

- (void)handleSwipeGesture: (UISwipeGestureRecognizer*)sender {
    [self performSegueWithIdentifier:@"konnichiwa" sender:self];
}