2012年4月29日日曜日

iPhoneアプリUniversal化



iPhoneアプリをiPadと使い分けするUniversalアプリに拡張する手順です。

Storyboardの追加Menu > New > File... > iOS > User Interface > Storyboard  [Next]

Device Family > iPad  [Next]
   
保存先にlprojフォルダを選択する。ファイル名はなんでもよいが、XcodeでUnivarsalプロジェクトを作る場合は"MainStoryboard_iPad.storyboard”になる。

プロジェクトの変更iPhoneからUniversalに変更する。

iPad用のセクションが追加される。
Storyboardを1で作成した名前に変更する。

Storyboardの設定

iPhoneと同じ部品を配置していく場合は同じ要領で行えばよいのですが、SplitViewをStoryboardを使用する場合は少し注意が必要です。パレットからUISplitViewをStoryboardに配置し、そのままビルド/実行すると白い画面が表示されます。UISplitViewは初期状態では左側のMasterビューが表示されません。横方向表示にすると表示されるのですが、初期状態では縦方向のみの表示となっています。
Masterビューを表示させるには、次の方法があります。

縦・横位置変更時にナビゲーションバーにMasterの表示/非表示切り替えをボタンを配置する方法(フレームワークの標準)
  • iPhoneアプリのメイン画面用のクラス、あるいは右側のDetailView用のクラスを作り、DetailViewのクラスに設定する。(以下MyDdtailViewControllerとする。)
  • @interfaceに
    UISplitViewControllerDelegateプロトコルを追加し、少なくとも次のデリゲートメソッドを追加し、パラメータで渡される(UIPopoverController *)pcをインスタンス変数に保持する。(初期状態が縦方向の場合は表示前にも呼ばれる。)
    - (void)splitViewController:(UISplitViewController *)svc
                   willHideViewController:(UIViewController *)aViewController
                                    withBarButtonItem:(UIBarButtonItem *)barButtonItem
                               forPopoverController:(UIPopoverController *)pc
    {
          popoverController = pc;
    }
  • アプリケーションデリゲートの
    didFinishLaunchingWithOptions、ないしはUISplitViewControllerの
    viewDidLoadでMyDdtailViewControllerオブジェクトをSplitViewのdelegateに設定する。(下の"Xcodeが作るアプリケーションデリゲートのメソッド"参照)
  • Detailのナビゲーションバーにボタンを追加し、アクションメソッドでMasterビューを表示させる。(ボタンはMasterView非表示時のみ表示するのが望ましい。)
    - (IBAction)showMaster:(id)sender
    {
        [popoverController presentPopoverFromBarButtonItem:sender                              permittedArrowDirections:UIPopoverArrowDirectionAny
                                                             animated:YES];    
左側のビューを常に表示させておく方法(iPadの設定画面などで使われている方法)
  • UISplitViewControllerのサブクラスを作り、StoryboardのSplitViewに設定する。
  • shouldAutorotateToInterfaceOrientationをオーバライドする。
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return YES;}
横位置表示に対応する

横位置でも表示されるようにするにはUISplitViewControllerのサブクラスで次のメソッドをオーバライドします。Master、Detailのクラスで行っても効果ありません。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
   return YES;
}

Xcodeが作るアプリケーションデリゲートのメソッド

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
        UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
        splitViewController.delegate = (id)navigationController.topViewController;
    }

横位置を許す場合はUISplitViewControllerのサブクラスを作る必要があるので、その場合はそのクラスのviewDidLoadで同等のロジックを実装することができます。

- (void)viewDidLoad
{
    [super viewDidLoad];
    UINavigationController *navigationController = [self.viewControllers lastObject];
    self.delegate = (id)navigationController.topViewController;     
}

Universal化する前に多言語対応している場合に次のエラーが発生することがあります。その場合はiPhoneの言語設定を行うと解消します。

reason: 'Could not find a storyboard named 'MainStoryboard_iPad' in bundle NSBundle ...

0 件のコメント: