LoginSignup
69
64

More than 5 years have passed since last update.

[Objective-C] UIViewControllerの回転周りのまとめ

Last updated at Posted at 2014-03-15

コードによる回転の制御

どうもiOS6あたりから制御方法が変わったらしい。
それまではshouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientationメソッドで制御していたが、今はふたつのメソッドで制御するぽい。

//ここで回転していいかの判別をする
- (BOOL)shouldAutorotate
{
    if (/* なにがしかの回転していいかの判定処理 */) {
        return YES;
    }

    return NO;
}

//どの方向に回転していいかを返す(例ではすべての方向に回転OK)
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

ちなみに回転のタイミングでなにかしたい場合。

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
    //回転時に処理したい内容
}

shouldAutorotateが呼ばれない場合

こちらの記事に書いてありました。
記事では、self.window.rootViewControllerに、自分で作成したUINavigationControllerを設定していると動作しないようです。
回転をコードから制御したい場合は、UINavigationControllerのサブクラスを作り、そちらに上記デリゲートメソッドを実装することで制御可能なようです。

サンプルコード

@interface HogeNavigationController : UINavigationController

@end

/////////////

@implementation HogeNavigationController

- (BOOL)shouldAutorotate
{
    return YES; // or NO
}

- (NSUInteger)supportedInterfaceOrientations
{
    // ポートレイトだけ許可
    return UIInterfaceOrientationMaskPortrait;
}

@end

UINavigationControllerのカテゴリで対処する

ただ、回転のためだけに継承するのもあれなので、ということでカテゴリで対応する方法のほうがスマートかもしれません。

【UINavigationControllerの子ViewControllerにも回転イベントを伝える】
これには、カテゴリによる拡張を使うことでシンプルに解決できます。

@implementation UINavigationController (Rotation)

- (NSUInteger)supportedInterfaceOrientations
{
    return [self.viewControllers.lastObject supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotate
{
    return [self.viewControllers.lastObject shouldAutorotate];
}
@end
参考
解説

UINavigationControllerのカテゴリで回転に関するdelegateをオーバーライドします。

その上で、自身のviewControllersの最後のViewControllerにも回転系のメッセージを送ります。
理由としては、( 上記リンクの下の記事を見てもらうと分かりますが )仕様的にrootViewControllerにUINavigationControllerが設定されている場合、その子ViewControllerには回転系のメッセージは送られないようです。
そのために、カテゴリで拡張し、最後ViewControllerの(つまり現在表示されてる)ViewControllerにメッセージを送っている、というわけです。


イベントの発生順

  1. shouldAutorote
  2. supportedInterfaceOrientations
  3. willRotateToInterfaceOrientaion:duration:

起動時の取得

起動時の画面の向きを取得するには、UIViewControllerのプロパティinterfaceOrientationを利用すればいいようです。

UIInterfaceOrientation direction = self.interfaceOrientation;
if(direction == UIInterfaceOrientationPortrait){
    // 縦(ホームボタンが下)
}
else if(direction == UIInterfaceOrientationPortraitUpsideDown){
    // 縦(ホームボタンが上)
}
else if(direction == UIInterfaceOrientationLandscapeLeft){
    // 横(ホームボタンが左)
}
else if(direction == UIInterfaceOrientationLandscapeRight){
    // 横(ホームボタン右)
}
69
64
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69
64