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

[iOS][Xcode 4.2]UITabBarController をルートコントローラーとして画面を回転する

 一発目、ちょいテクニカルな記事。というか、備忘録。学生のときのノートって偉大だよね。後から見直す訳ではないんだけど、1度でも書くってことで記憶に残るんだわ。うん。

 

 UITabBarController をルートコントローラーとして(つまりは、Tabbed Applicationのテンプレートを選択した場合) アプリを作った場合、特定のタブが選択された場合だけ画面の回転 (Rotate) を許可しようとすると、意外とめんどくさい。

 というのも、UITabBarController を回転させたい場合、その時表示されているタブのビューコントローラーが回転可能でなければならないからなんです。

 Tabのアプリを作る場合、タブの中に表示したい物をそれぞれ FIrstViewController / SecondViewController とし、それぞれが単なる UIViewControllerのサブクラスだとすると

  • UITabBarController
    • Tab 1 : FirstViewController (UIViewControllerのサブクラス)
    • Tab 2 : SecondViewController (UIViewControllerのサブクラス)

みたいな構成にしてこんな画面になる。

 

 画面の回転自体は、単なるシングルビューアプリの場合、回転させたいUIViewControllerのサブクラスの shouldAutorotateToInterfaceOrientation メソッドの戻り値を YES にすればよい。(正しくは、回転が必要な方向の場合のみYESを返すんだけど、この辺りの事は普通に本とか、他のページにも書いてあるので)

 もちろんレイアウトの調整とか、回転させた時のアニメーションとか設定する必要はあるけど、それはまた別の話。

 話を元に戻す。なので、上の例で言うとTab 1 を回転させたいのなら FirstViewController の shouldAutorotateToInterfaceOrientation メソッドの戻り値を YES にしてあげれば良いような気がする。ところが、これだけでは回転してくれない。冒頭にお話しした通り、この時 Tab に割り付けられている全ての ViewControllerサブクラスが回転可能でなければ回転してくれいないのだ。

 と、すれば、勿論 Tab 2 の SecondViewController の shouldAutorotateToInterfaceOrientation メソッドの戻り値も YESにしてあげれば良い。

 よい、のだけど、今度は別の問題。回転させたいのは今回、FirstViewController だけなのだ。

 「片方だけ回したいのに両方設定しなきゃ回転自体してくれなくて、でもそうすると両方回ってしまう」というジレンマ。

  一日ばかり悩んだ結果出した答えは

「結局、今何を表示しているかをモードで持っていれば良い」

 ということ。

 

 今回は、特定のクラスにStatic変数を持たせて、その変数でモードを管理する事にした。

 例えば

//
// ModeManager.m
// Penguin3
//
// Created by Issou Ohuchi on 11/11/12.
// Copyright (c) 2011年 brocken records. All rights reserved.
//

#import "ModeManager.h"

static NSInteger dispMode;  // 現在表示しているモードを格納するスタティック変数

@implementation ModeManager
// 現在表示中のモードを取得するクラスメソッド
+(NSInteger)GetMode{
    return dispMode;
}

// 現在表示中のモードを設定するクラスメソッド
+(void)SetMode:(NSInteger)modeId{
    dispMode = modeId;
}
@end



みたいな単純なクラス(メソッド定義だけのヘッダは省略) を作って現在の表示モードを管理し、各UIViewControllerのサブクラスの shouldAutorotateToInterfaceOrientation メソッドで、現在表示中の画面が回転させたい表示モードであるかというのを合わせて判断すれば良い…という事にした。

 正しい作り方じゃない様な気がするんだけど、これで上手くいったので、良しとしたい。