2012年09月20日

【iPhone SDK】iOS6の画面回転対応が大幅に変更に伴う修正

はい、iOS6になっていろいろ不具合が発生しております。

iPadアプリにて画面の回転処理があるのですが、
iOS6からはいままでの

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

が使えなくなりました。


まずInfo.plistのSupported Interface Orientationsに指定した回転が反映されるようで、
すべて選択していた状態だけどshouldAutorotateToInterfaceOrientationにて
ポートレートのみYESにしていた場合、iOS5までは縦画面のみになりますが
iOS6では回転されてしまうようです。

まずは不要な回転状態は外しておきましょう。

プログラム上で指定をすることで回避することもできます。

UIViewControllerに新しくメソッドが追加されており、
対応していく必要があります。UIViewControllerのクラス内に以下の2つを実装する必要があります。

- (BOOL)shouldAutorotate

- (NSUInteger)supportedInterfaceOrientations


shouldAutorotateの場合、端末の回転が発生した時に自動で回転するかどうかのフラグになります。
基本YESでいいでしょう

今まで回転を許可していた部分の指定はsupportedInterfaceOrientationsで行うようになりました。

returnする値にUIInterfaceOrientationMaskの列挙体を指定します。


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations.
    return ((interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft));
}

と今まで横持ち限定を指定していた場合


- (NSUInteger)supportedInterfaceOrientations{
     return UIInterfaceOrientationMaskLandscape;
}

と指定します。

UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortraitUpsideDown

が基本指定する値になります。

UIInterfaceOrientationMaskLandscape → Left+Rightの横限定回転
UIInterfaceOrientationMaskAll → すべての回転
UIInterfaceOrientationMaskAllButUpsideDown → UpDown以外のすべて

と予めセット指定も宣言されています。

でも自分は回転処理が反映されず、横画面アプリなのに縦画面のまま表示され自動回転処理が実行されませんでした。


原因を3時間かけて調べていたら
最初の設定で失敗していることがわかりました。


iOS4からUIWindowクラスにrootViewControllerのプロパティが設定されていたのですが、
それ以前のやり方でUIViewControllerをUIWindowに登録していたのが原因でした。


[self.window addSubview: rootViewController.view];

としていたのが原因でした。

[self.window setRootViewController: rootViewController];

と設定するときちんと回転処理が実行されました。
モーダルビューコントローラーの回転処理もこれに変更することによって実行されました。


なんかNavigationControllerをrootViewControllerに指定していると
各ViewController上でプログラム制御しても反映されないなぁ…

まさかとは思うけどNavigationControllerクラスをサブクラス作って
回転制御を書かないといけないのか・・・?

調べてまたまとめます。



*********

追記
UINavigationControllerも所詮はViewControllerなので
サブクラス化してsupportedInterfaceOrientationsをオーバーライドしてやる必要があるようです。

@interface CustomNavigationController: UINavigationController;

@end

というカスタムナビゲーションコントローラークラスを作成し

- (NSUInteger)supportedInterfaceOrientations{
    return self.topViewController.supportedInterfaceOrientations;
}

オーバーライドメソッドにはトップビューコントローラーの値を返すようにしました。

これによってNavigationControllerにプッシュされたViewCOntrollerクラスに定義されている
supportedInterfaceOrientationsの値が反映されることとなります。


ラベル:iPhone Xcode
posted by ヒイロ at 14:57| 福岡 ☁| Comment(3) | TrackBack(0) | プログラム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
一番最後の追記が非常に役に立ちました。
数日悩んで発狂しそうだったのですごくうれしいです!
詳しい経緯を書いていただき本当にありがとうございました。
Posted by Bambi at 2012年09月21日 00:04
>>Bambiさん
解決の手立てができて嬉しく思います。
実際にAppStoreへの申請には出していないので
その手順で問題ないのかはわかりませんので
ご注意ください。
10月くらいはそのプロジェクトが納品になり、申請に入ると思います。
その時にまた改めて報告したいと思っております。
もしBambiさんの方で早期にAppStoreの審査が通過できましたらお知らせいただければとおもいます。
Posted by ヒイロ at 2012年09月23日 11:59
今日、この対応を実装しているアプリがAppStoreへ公開となりました。

結果、問題ないことが証明できたかと思います。
仕事でのアプリなので名前は公表できませんが、とりあえず報告です。
Posted by ヒイロ at 2012年11月06日 17:40
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。