【iOS開発】iPhone毎に表示するStoryBoardを変更する方法

【iOS開発】iPhone毎に表示するStoryBoardを変更する方法

iOS開発を行う上での共通課題はiPhone毎に解像度が異なる点です。iPhone6,iphone6Plus(その後、iphone6s,iphone6sPlus)の発売を受けてさらにその影響度が増し、対応に追われる必要性が出てきました。

私もその例外ではなく、いま初めて作成しているアプリでも同じような課題を検討する必要があり、対応策について色々と調べて何案かあるうちの1つを選択したので、その方法についてメモを残しておきます。

 

実現方法の選択

この課題についての解決方法についてはいくつかありました。

  1. iPhone毎に呼び出すStoryBoardを変更する
  2. iPhone毎にStoryBoardから呼び出されるUIImageViewを変更する
  3. AutoLayoutを駆使して全てのiPhoneに対応できるレイアウトを作成する

それぞれに対して、メリット・デメリットを下記にまとめます。

 

案1についてのメリット・デメリット

 

メリット

  • AppDelegateに記述をするだけで処理の振り分けが実現できる
  • コード記述数が少ない
  • 確実にiPhone毎の違いに対応できる

 

デメリット

  • StoryBoardをたくさん用意しないといけない
  • StoryBoardに変更がある際のStoryBoardへの影響範囲が大きい
  • それぞれのiPhone毎に画像を用意する必要がある

上記のようなメリット・デメリットがありますが、私は総合的に案1を選択しました。

 

案2のメリット・デメリット

 

メリット

  • 用意するStoryBoardは1つで済む
  • StoryBoardに対するメンテナンス性が高い

 

デメリット

  • iPhone毎に異なる背景画像等を準備する必要がある
  • UIImageViewの処理を実装部に記述する必要があるため、処理性能が気になる

案2で解決することも全然可能だったのですが、UIImageViewの扱いに長けていないことから、私はこの案2を避けました。

 

案3のメリット・デメリット

 

メリット

  • StoryBoardを複数用意する必要がない
  • 背景画像等を複数用意する必要が実現方法次第ではない
  • AppDelegate , 実装部に処理の記述を行わなくてもよい

 

デメリット

  • AutoLayoutで確実に実現したいアプリデザインが実現できるとは限らない
  • AutoLayoutがそもそも使いこなす事が難しい

きっと、AutoLayoutを使いこなせる人はこの案3がベストな答えなんだと思いますが、私はAutoLayoutをうまく使いこなす事ができないので、案3は避けました。

 

実装方法

案1を採用したのでAppDelegateに実装を行いました。
※前提条件として私の作成しているアプリはiPadは対象としていないです。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // アプリが起動された時のiphoneの画面サイズを元に利用されているiphoneの型を特定し起動するStoryboardを振分ける
    // height : 480px => iPhone4 or iPhone4S
    // height : 568px => iPhone5 or iPhone5S
    // height : 667px => iPhone6
    // height : 736px => iPhone6plus
    //
    
    // StoryBoardの型宣言
    UIStoryboard *storyboard;
    
    // StoryBoardの名称設定用
    NSString * storyBoardName;
    
    // 機種の取得
    NSString *modelname = [ [ UIDevice currentDevice] model];
    
    // iPadでないことの判定
    if ( ![modelname hasPrefix:@"iPad"] ) {
        
        NSLog(@"iphoneの判別OK");
        
        // 起動されているiPhoneのWindowSizeを取得
        CGRect r = [[UIScreen mainScreen] bounds];
        
        // iPhoneの判定
        if(r.size.height == 480){
            storyBoardName = @"iPhone4_4S";
        }
        else if (r.size.height == 568){
            storyBoardName = @"iPhone5_5S";
        }
        else if (r.size.height == 667){
            storyBoardName = @"iPhone6";
        }
        else if (r.size.height == 736){
            storyBoardName = @"iPhone6plus";
        }
        
        // 上記いづれにも該当しない場合:iPad もしくは iPhone3Sより古いバージョン
        else {
            NSLog(@"%f",r.size.height);
            storyBoardName = @"Main";
        }
        
    }
    
    // StoryBoardのインスタンス化
    storyboard = [UIStoryboard storyboardWithName:storyBoardName bundle:nil];
    
    // 画面の生成
    UIViewController *mainViewController = [storyboard instantiateInitialViewController];
    
    // ルートウィンドウにひっつける
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = mainViewController;
    [self.window makeKeyAndVisible];
    
    return YES;

 

実現方法としては、非情に単純。

  1. アプリを起動している端末の画面サイズを取得する
  2. 各iPhone毎に定められている、どの画面サイズと一致するかを判定する
  3. 条件に該当する画面サイズが、利用しているiPhoneであるため、端末の特定が出来る
  4. 特定した端末ごとに呼び出すStoryBoardを振分ける
  5. 指定した名前のStoryBoardを起動する

この方法が多分一番簡単で確実な方法だと思います。
若干StoryBoardに対するメンテナンス性が悪いですが、そこまで大きなアプリじゃない限りは問題無いと思います。

 

らいか
StoryBoardの切り替えってもっと標準で実装してくれてもいいよね。って思った。
【iOS開発】iPhone毎に表示するStoryBoardを変更する方法

ABOUTこの記事をかいた人

工業高等専門学校を卒業後、NTTグループのSI企業に就職。数々の炎上案件を鎮火するために日本各地を5年間転々とする。2015年に一般ユーザ向けのWebシステム開発案件のチームリーダとして業務に従事し、改めて"Webのものづくりの楽しさ"に気付きWeb制作会社に転職。Web制作やアクセス解析を使ったオウンドメディアの運用改善などを行っていく中で、もっとユーザー目線でWebをただ制作するだけではなく企画や運用まで幅広い領域で仕事がしたいと感じるようになり、Webディレクターのキャリアを目指す。日本中のビジネスホテルに詳しく、犬や猫よりも鳥派。