iPhone デバイスの回転を検出する : Objective-C プログラミング

PROGRAM


iPhone デバイスの回転を検出する

UIView の回転を検出する方法については、UIViewController であれば iPhone 回転時にオブジェクトをアニメーションで移動する のようにして回転を検出することができます。

それ以外の場面で回転を検出したい場合には、たとえば、通知センター(NotificationCenter)を使用して、iPhone 等のデバイスが回転した際に通知を受け取る方法があります。

この方法だと、デバイスが上や下を向いた時についても、知ることができます。

通知センターへの登録

デバイスが回転したとき、通知センターには UIDeviceOrientationDidChangeNotification という通知が届きます。

これを検知して、例えば "deviceDidRotate:" というメソッドを実行したい場合には、次のようなプログラミングを行います。

// 通知センターに回転通知が届いた際に実行したいメソッドを登録します。

[[NSNotificationCenter defaultCenter] addObserver:self selector@(deviceDidRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];

このようにすることで、デバイスが回転した時に、自分自身が持つ "deviceDidRotate:" メソッドが呼び出されるようになりました。

デバイスの回転が通知された場合の処理

呼び出される "deviceDidRotate:" メソッドには、通知が NSNotification 型で渡されてきます。

この中の "object" プロパティが持つ "orientation" の値を参照することで、デバイスの向きを取得することができるので、例えば次のような感じで、方向に応じた処理を行うことが可能になります。

// 通知センターに回転通知が届いた際に実行したいメソッドを登録します。

- (void)deviceDidRotate:(NSNotification*)note

{

// 回転の情報は note.object が持つ orientation プロパティで取得できます。

UIDeviceOrientation orientation = [note.object orientation];

 

if (UIDeviceOrientationIsPortrait(orientation))

{

// ここではデバイスが縦方向(逆さまを含む)の場合の処理を行います。

 

}

else if (UIDeviceOrientationIsLandscape(orientation))

{

// ここではデバイスが横方向の場合の処理を行います。

 

}

}

上記では、縦方向か横方向かを判定するのに、それぞれ "UIDeviceOrientationIsPortrait" マクロと "UIDeviceOrientationIsLandscape" マクロを使用していますが、iOS 5 SDK では、具体的には次の回転状態を得られるようになっていました。

UIDeviceOrientationUnknown デバイスの回転状態が不明の場合もあるようです。
UIDeviceOrientationPortrait デバイスが縦方向(ホームボタンが下)の場合です。
UIDeviceOrientationPortraitUpsideDown デバイスが縦方向(ホームボタンが上)の場合です。
UIDeviceOrientationLandscapeLeft デバイスが横方向(ホームボタンが右)の場合です。
UIDeviceOrientationLandscapeRight デバイスが横方向(ホームボタンが左)の場合です。
UIDeviceOrientationFaceUp デバイスが水平で、画面が上の場合です。
UIDeviceOrientationFaceDown デバイスが水平で、画面が下の場合です。

このように、デバイスの方向は UIViewController の方向とは違って、縦横方向以外にも、水平の場合や不明な場合もあります。

通知センターからはこのようなさまざまな状態が通知されてくるので、縦か横かそれ以外かといったように、注意して向きを判定する必要があります。

通知センターでデバイスの方向を知るための事前準備

また、ドキュメントによると、このデバイスの向きを通知センターから受け取るためには、事前に次の命令を実行しておく必要があるとのことでした。

// 通知センターからデバイスの方向を知るための事前準備

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

この命令を実行しておかないと、UIDeviceOrientationDidChangeNotification 通知での orientation の情報が更新されないらしいのですけど、自分で試してみた感じでは、どこかでこのメソッドが呼び出されているのか、回転情報を取得できる感じでした。

 

このメソッドは入れ子にして呼び出すことができるそうなので、通知センターでデバイスの回転を検出したい場合には、もしどこかで呼び出されていたとしても、自分自身も適切な場所で呼び出してあげるようにするのが安全かもしれません。

この "beginGeneratingDeviceOrientationNotifications" メソッドを呼び出したら、検出が不要になった最後に必ず、次のメソッドを呼び出す必要があるとのことでした。

// 通知センターからのデバイスの方向を知る必要がなくなった場合の後処理

[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];

入れ子にして呼び出す場合も含めて、"beginGeneratingDeviceOrientationNotifications" と "endGeneratingDeviceOrientationNotifications" とが必ず同じ数だけ呼び出されるように注意します。

通知センターからの登録解除

デバイスの回転通知を受け取る必要がなくなったら、次のようにして、通知センターからの呼び出しを受け取らないようにします。

// 通知センターからの呼び出しを解除します。

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

または、次のように簡単に、たとえば自分自身 (self) へ通知される通知全ての登録解除を行うこともできます。

// 自分自身に関連する全ての通知を、通知センターから解除します。

[[NSNotificationCenter defaultCenter] removeObserver:self];

最後にはこれらのようにして、通知センターからの通知を受け取らないようにします。

[ もどる ]