PortraitとLandscapeの正しい判定

デバイスのポートレイトとランドスケイプを判定する処理をなんとなく以下のように書いていた。

+ (BOOL)isDevicePortrait
{
    UIDevice* d = [UIDevice currentDevice];
    return (d.orientation == UIDeviceOrientationPortrait ||
            d.orientation == UIDeviceOrientationPortraitUpsideDown);
}
+ (BOOL)isDevicelandscape
{
    UIDevice* d = [UIDevice currentDevice];
    return (d.orientation == UIDeviceOrientationLandscapeLeft ||
            d.orientation == UIDeviceOrientationLandscapeRight);
}

しかしこのコードでは正しく判定できない。というのも[UIDevice currentDevice]は上記以外にも以下の定数を戻すからだ。

UIDeviceOrientationFaceUp
UIDeviceOrientationFaceDown

一般的なアプリケーションのように画面の再描画、再レイアウトをするだけなのであれば、ポートレイトかランドスケイプを判定すれば良く上記のFaceUp/FaceDownは不要である。しかし、不要だからといってこれらの値が入ってこないようにフィルタすることもできない。

ならばどうするか?

+ (BOOL)isDevicePortrait
{
    UIInterfaceOrientation o = [[UIApplication sharedApplication] statusBarOrientation];
    return (o == UIDeviceOrientationPortrait ||
            o == UIDeviceOrientationPortraitUpsideDown);
}
+ (BOOL)isDevicelandscape
{
    UIInterfaceOrientation o = [[UIApplication sharedApplication] statusBarOrientation];
    return (o == UIDeviceOrientationLandscapeLeft ||
            o == UIDeviceOrientationLandscapeRight);
}

上記のコードのようにUIInterfaceOrientationはFaceUp/FaceDownは定義されておらず、statusBarOrientationでは戻らないため、縦か横かだけで判定することができる。

これでOKなのだが、その後更に調べると向きを判定しているコードがマクロとして登録されており、メソッドすら用意する必要がなかった。

BOOL isDevicePortrait = UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]);
BOOL isDevicelandscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);

うーん、まだまだ修行が足りないな。