読者です 読者をやめる 読者になる 読者になる

ニペブ - iPhone / iOSアプリ開発

iPhone / iOS アプリ開発方法と技術情報、入門レベルの初心者向けの記事を書いています。

(iOS/iPhoneアプリ開発) UISegmentedControlを使って画面表示 UIViewController を切り替える

完成イメージ

完成イメージは次の通りです。
上側のセグメンテッドコントロール(UISegmentedControl)をクリックすると、その下側のビューが変わります。
f:id:nipe880324:20131221193703p:plain:w240

("Second"を選択した後)
f:id:nipe880324:20131221193709p:plain:w240

環境

StoryBoardの作成

まずは、次のように3つのStoryBoardを作成します。(左や上側のコントローラは気にしないでください。)
f:id:nipe880324:20131221194110p:plain

  1. UIViewControllerを追加(3つのViewControllerのうち左側のViewController)
  2. 上記のコントローラの「Custom Class」にクラス名を設定(今回は、"TwoViewsViewController"を設定)
  3. 上記のコントローラにUISegmentedControlとUIView(切り替えるコンテンツの表示領域になる)を追加
  4. StoryBoardとViewController.hの2つのビューにし、「Ctrl + ドラッグ」を使って、上記のUISegmentedControlとUISegmentedControlをViewController.hに追加。※SegmentedControlはIBActionとIBOutletの両方を追加。
  5. 切り替え対象のコントローラを作成(今回はUITableViewControllerとUIViewControllerを作成)
  6. 切り替え対象のコントローラのそれぞれの「Storboard ID」と「Restoration ID」に識別子を設定(今回はテーブルビューに"FirstViewController"、ノーマルのビューに"SecondViewController"を設定)

ViewController.hに次のような記述が記載されます。

// セグメンテッドコントローラ
@property (weak, nonatomic) IBOutlet UISegmentedControl *typeSegmentedControl;
// 切り替えるコンテンツを表示させる領域
@property (weak, nonatomic) IBOutlet UIView *contentView;
// SegmentedControlの値を変更したときに呼ばれる
- (IBAction)segmentChange:(UISegmentedControl *)sender;

ViewController.hの作成

次に、ViewController.h を作成します。
詳細はコメントを確認してください。

#import <UIKit/UIKit.h>

@interface TwoViewsViewController : UIViewController

// セグメンテッドコントローラ
@property (weak, nonatomic) IBOutlet UISegmentedControl *typeSegmentedControl;

// 切り替えるコンテンツを表示させる領域
@property (weak, nonatomic) IBOutlet UIView *contentView;

// 現在のViewControllerを保持しておく変数
@property (weak, nonatomic) IBOutlet UIViewController *currentViewController;

// SegmentedControlの値を変更したときに呼ばれる
- (IBAction)segmentChange:(UISegmentedControl *)sender;
@end

ViewController.mの作成

次に、ViewController.m を作成します。

実際のソースコードです。
細かくコメントを記載してますのでそれを見れば大体分かると思います。

#import "TwoViewsViewController.h"

@implementation TwoViewsViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
 
    // SegmentedControlの値により異なるControllerを取得する
    UIViewController *vc = [self viewControllerForSegmentIndex:self.typeSegmentedControl.selectedSegmentIndex];
    // 取得したコントローラを子コントローラとして追加する
    [self addChildViewController:vc];
 
    // 子コントローラのViewを親コントローラのContent表示領域のサイズにする
    // スクロール対応していない場合などは画面から見切れる可能性があるので気をつけてください
    vc.view.frame = self.contentView.bounds;

    [self.contentView addSubview:vc.view];
    self.currentViewController = vc;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

// SegmentedControlの値により異なるControllerを取得する
- (UIViewController *)viewControllerForSegmentIndex:(NSInteger)index {
    UIViewController *vc;
    switch (index) {
        case 0:
            vc = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstViewController"];
            break;
        case 1:
            vc = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
            break;
    }
    return vc;
}

// SegmentedControlの値を変更したときに呼ばれる
- (IBAction)segmentChange:(UISegmentedControl *)sender
{
    // SegmentedControlの値により異なるControllerを取得する
    UIViewController *vc = [self viewControllerForSegmentIndex:sender.selectedSegmentIndex];
    // 取得したコントローラを子コントローラとして追加する
    [self addChildViewController:vc];
    // ビューを変更する
    [self transitionFromViewController:self.currentViewController toViewController:vc duration:0.5
     options:UIViewAnimationOptionTransitionCurlUp  // 変更するアニメーションを指定
     animations:^{
        [self.currentViewController.view removeFromSuperview];
        vc.view.frame = self.contentView.bounds;
        [self.contentView addSubview:vc.view];
    } completion:^(BOOL finished) {
        [vc didMoveToParentViewController:self];
        [self.currentViewController removeFromParentViewController];
        self.currentViewController = vc;
    }];
}

@end


UISegmentdControlなどのUIKitに関するサンプルのソースコードGithubに置いてあります。よろしければ、覗いてみてください。
yanagi0324/test-uikit · GitHub

参考情報

分かりづらい箇所やご質問などありましたら、 コメントやメールアドレスにご連絡いただけると嬉しいです。