24/7 twenty-four seven

iOS/OS X application programing topics.

iPhoneの回転をshouldAutorotateToInterfaceOrientation:以外の方法で検知する。

http://iphone.longearth.net/2009/05/10/os30%E3%81%AEshouldautorotateto-interfaceorientation%E3%81%8C%E3%81%8A%E3%81%8B%E3%81%97%E3%81%84%E4%BB%B6
iPhone OS 3.0 - Breaking changes to shouldAutorotateToInterfaceOrientation | blog.sallarp.com
shouldAutorotateToInterfaceOrientation? | blog.sallarp.com


上記では加速度センサの値から、デバイスの方向を判断する方法が載っているのですが、たいていの場合は回転したときに発生するNotificationを捕まえるのが簡単だと思いますので書いておきます。


UIDeviceOrientationDidChangeNotificationはUIDevice.hで定義されている定数です。
デバイスの向きが変わった時に、通知を受けられるように、アプリケーションの起動時や(applicationDidFinishLaunching:)、ビューのロード時(viewDidLoad)で登録するといいでしょう。

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didRotate:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];

上記のように書いておくと、デバイスの向きが変わった時に登録したメソッド (上記ではdidRotate:)が呼ばれます。


ちなみに、beginGeneratingDeviceOrientationNotificationsを呼ばなくても通知が来ます。
ドキュメントによると、通知は来ますが、orientationの値が常にゼロ(UIDeviceOrientationUnknown)になるということです。


通知先のメソッドで、改めて現在の方向を判断して、いろいろします。

- (void) didRotate:(NSNotification *)notification {
    UIDeviceOrientation orientation = [[notification object] orientation];

    if (orientation == UIDeviceOrientationLandscapeLeft) {
        ...
    } else if (orientation == UIDeviceOrientationLandscapeRight) {
       ...
    } else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
       ...
    } else if (orientation == UIDeviceOrientationPortrait) {
       ...
    }
}

また、通知はタテ、ヨコの変化以外に上向き(UIDeviceOrientationFaceUp)、下向き(UIDeviceOrientationFaceDown)に変わった場合でも飛んできますので、条件文の最後をelseでまとめてしまったりすると、変な時に画面を回転してしまったりしますので気をつけましょう。