iOSアプリの画面である方向だけでしか使わせないような設定をすることはよくある。縦画面だけ、横画面だけというレイアウトの都合上どうしてもその必要があるものは多い。

そういう時に使うメソッド/設定方法や記述方法はiOSの進化とともに変化しているが、現状アプリ全体でならInfo.plist (Supported interface orientations)が最適じゃないかと思う。が、ビューごとに使える画面方向が違うというのであればViewControllerでの supportedInterfaceOrientations メソッドが便利かと思う。
var supportedInterfaceOrientations: UIInterfaceOrientationMask { get }

※ただし、iOS 8以降では画面サイズが増え、さらに複数アプリの同時表示などの機能が登場するなどしたため、 UITraitCollectiontraitCollection プロパティを使うことが推奨されている。

このメソッドで使える向きを返す。UIInterfaceOrientationMask は、OptionSet プロトコルを実装した構造体で、rawValueはInt型。これはObjective-C時代や初期のSwift(Swift1)の頃はUInt型のビットマスクで実現されていた。ところが構造体のインスタンスはビット演算などができなくなった。では複数の方向を組み合わせるにはどうすればいいのだろうか?


Objective-C時代には例えば
unsigned unitFlags = UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight
unsigned unitFlags = UIInterfaceOrientationMaskLandscapeLeft + UIInterfaceOrientationMaskLandscapeRight
などの整数演算で組み合わせを作っていた。



実際、よく使う組み合わせは便利のため、予め定義されている。
Constantsportraitupside-down portraitlandscape-rightlandscape-leftrawValue
portrait×××2(0 0010)
portraitUpsideDown×××4(0 0100)
landscapeRight×××8(0 1000)
landscapeLeft×××16(1 0000)
landscape××24(1 1000)
all30(1 1110)
allButUpsideDown×26(1 1010)


これを見てわかるように、左右の横画面は定義済みだが縦方向は両方を組み合わせた物はない。 allButUpsideDown があるように、縦方向(逆さま向き)で使うことはあまりないようだ。それでも逆さ方向で使いたいときにどうするのか?

Swift3, Swift4での書き方は下記。
var supportedInterfaceOrientations: UIInterfaceOrientationMask { 
    return [ portrait, portraitUpsideDown ]
} 


なぜそうなるのかの詳細は類似記事を参照してください。


let portrait = UIInterfaceOrientationMask.portrait
print(portrait.rawValue) // 2
let portraitUD = UIInterfaceOrientationMask.portraitUpsideDown
print(portraitUD.rawValue) // 4
let landscapeRight = UIInterfaceOrientationMask.landscapeRight
print(landscapeRight.rawValue) // 8
let landscapeLeft = UIInterfaceOrientationMask.landscapeLeft
print(landscapeLeft.rawValue) // 16
let landscape = UIInterfaceOrientationMask.landscape
print(landscape.rawValue) // 24
let all = UIInterfaceOrientationMask.all
print(all.rawValue) // 30
let allButUD = UIInterfaceOrientationMask.allButUpsideDown
print(allButUD.rawValue) // 26
let lr = UIInterfaceOrientationMask([landscapeLeft, landscapeRight])
print(lr.rawValue) // 24
if landscape == lr {
    print("Same!") // "Same!"
} else {
    print("different")
}