UIUserInterfaceSizeClassという現在のデバイスの向きの縦横の対応しているサイズを表現するクラスが追加されました。
これを使って、StoryboardのUIをiPhone 6 PlusやiPadとその他でも共存できるようになりました。
また、UIScreenのbounsの値もきちんと向きに合わせて表示されるように変更となりました。
以前までは、向きによって縦横を入れ替えたりしていたので、これは若干注意が必要なところです。
xcode,iOS8,iPhone – iOSのマルチデバイス対応 UITraitCollection – Qiita
[iOS 8] マルチデバイス対応の新機能「Trait Collection」 | Developers.IO
そういった変化には柔軟に対応していきたいのですが、最近iPhone 6 Plusかどうかを判定する必要があり、そういったときにこのUIUserInterfaceSizeClassとUIScreenのサイズを使って切り分けるコードを書きましたので、記事にしておきます。
※全て、UIViewControllerのカテゴリとして書いています。
まず、UIScreenのサイズを見て、ランドスケープか、ポートレイトか判断します。
func isPortrait() -> Bool {
let size = UIScreen.mainScreen().bounds.size
if size.width > size.height {
return false
} else {
return true
}
}
func isLandscape() -> Bool {
let size = UIScreen.mainScreen().bounds.size
if size.width > size.height {
return true
} else {
return false
}
}
また、iPhone 6 Plusのポートレイト時の横幅は、414.0ポイントなのでそれも判定します。
func has414pt() ->Bool {
if isPortrait() &&
UIScreen.mainScreen().bounds.size.width == 414.0{
return true
}
if isLandscape() &&
UIScreen.mainScreen().bounds.size.height == 414.0{
return true
}
return false
}
UITraitCollectionの縦横の条件をiPhone 6 Plusの仕様に合わせて判定します。
iPhone 6 PlusはPortrait時には、縦がRegularで、横がCompactです。
Landscape時には、縦がCompactで、横がRegularになります。
それらを組み合わせて、isIphone6Plus()という関数にしました。
func isIphone6Plus() -> Bool {
if traitCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: UIUserInterfaceSizeClass.Regular)) &&
traitCollection.containsTraitsInCollection(UITraitCollection(horizontalSizeClass: UIUserInterfaceSizeClass.Compact)) &&
has414pt(){
return true
} else if traitCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: UIUserInterfaceSizeClass.Compact)) &&
traitCollection.containsTraitsInCollection(UITraitCollection(horizontalSizeClass: UIUserInterfaceSizeClass.Regular)) &&
has414pt(){
return true
}
return false
}
とこんな感じになります。
ここまで書いて思いましたが、iPhone 6 Plusと同じサイズのデバイスは他にないので414.0ptかどうかの判断だけでも良いかもしれません。
そもそも実機であれば、ハードウェアの情報から判定できますがシミュレータでもiPhone 6 Plusかどうか判定したかったので、上記のような方法を取りました。
//ハードウェアの情報を取得するコード
func device () ->String {
var size : UInt = 0
sysctlbyname("hw.machine", nil, &size, nil, 0)
var machine = [CChar](count: Int(size), repeatedValue: 0)
sysctlbyname("hw.machine", &machine, &size, nil, 0)
return String.fromCString(machine)!)
}
さいごに、UIViewControllerのカテゴリは以下のようなものです。
extension UIViewController {
func isIphone6Plus() -> Bool {
if traitCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: UIUserInterfaceSizeClass.Regular)) &&
traitCollection.containsTraitsInCollection(UITraitCollection(horizontalSizeClass: UIUserInterfaceSizeClass.Compact)) &&
has414pt(){
return true
} else if traitCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: UIUserInterfaceSizeClass.Compact)) &&
traitCollection.containsTraitsInCollection(UITraitCollection(horizontalSizeClass: UIUserInterfaceSizeClass.Regular)) &&
has414pt(){
return true
}
return false
}
private func has414pt() ->Bool {
if isPortrait() &&
UIScreen.mainScreen().bounds.size.width == 414.0{
return true
}
if isLandscape() &&
UIScreen.mainScreen().bounds.size.height == 414.0{
return true
}
return false
}
func isPortrait() -> Bool {
let size = UIScreen.mainScreen().bounds.size
if size.width > size.height {
return false
} else {
return true
}
}
func isLandscape() -> Bool {
let size = UIScreen.mainScreen().bounds.size
if size.width > size.height {
return true
} else {
return false
}
}
}