ナビゲーションバー高さ | ステータスバー高さ | safeareaInsets.top | |
---|---|---|---|
iPhone12mini | 44 | 44 | 50 |
iPhone12 | 44 | 47 | 47 |
iPhone12Pro | 44 | 47 | 47 |
iPhone12ProMAX | 44 | 47 | 47 |
iPhone11 | 44 | 48 | 48 |
iPhone11 Pro | 44 | 44 | 44 |
iPhone11 Pro Max | 44 | 44 | 44 |
iPhoneX | 44 | 44 | 44 |
iPhoneXR | 44 | 44 | 44 |
iPhoneXS | 44 | 44 | 44 |
iPhoneXS Max | 44 | 44 | 44 |
iPhoneSE | 44 | 20 | 20 |
iPhone8 | 44 | 20 | 20 |
iPhone8 Plus | 44 | 20 | 20 |
要約
-
ナビゲーションバーの高さは全て同じで44ptになっています。
-
ステータスバーは、ノッチ付きの端末(iPhone X以降)だと、それ未満の端末より大きく、40pt台となっています。特にiPhone12系で変化が不規則なので注意が必要です
-
iPhone 12 miniでのみ、余白があることによりステータスバーの高さでは正しい距離が取れなくなってしまいました。
UIView
のsafeAreaInsets.top
を使うと正しい距離が取れます。- ただし親である
UIViewController
のviewWillLayoutSubviews
が呼ばれるまでは値が0になっているので待つ必要があります。またviewWillLayoutSubviews
は何度でも呼ばれる可能性があるので注意してください。 -
UIWindow
のsafeAreaInsets.top
を使ってもいいと思います(UIWindow
はUIView
のサブクラス)。これを使って高さを取得する一例は以下になります。
- ただし親である
var safeAreaTopInsets: CGFloat
if #available(iOS 11.0, *) {
if let topInsets = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.safeAreaInsets.top,
topInsets > 0 {
safeAreaTopInsets = topInsets
}
} else {
safeAreaTopInsets = UIApplication.shared.statusBarFrame.size.height
}
以下のようなextensionを作るとやりやすいかと思います。
.UIView+StatusBarHeight.swift
import Foundation
extension UIView {
/// ステータスバーの領域の高さを返す。UIApplication.shared.statusBarFrame.size.heightでは、iOSバージョン・端末の種類によっては正しい値を取れないことがあるためこれを用いる。
/// https://qiita.com/satoru_pripara/items/73f4ae47fa2726332e95
var statusBarAreaHeight: CGFloat {
var statusBarHeight: CGFloat
if #available(iOS 11.0, *) {
//iOS11, iPhone8 or iPhone8 plus でsafeAreaInsets.topが0になる事がある
statusBarHeight = (safeAreaInsets.top > 0.0) ? safeAreaInsets.top : UIApplication.shared.statusBarFrame.size.height
} else {
statusBarHeight = UIApplication.shared.statusBarFrame.size.height
}
return statusBarHeight
}
}
参考
[iOS] iPhone12 miniでStatusBarの高さ取得が期待した動作をしないのと対策
【iOS】safeAreaInsetsの値が取得できるタイミング
How to resolve: 'keyWindow' was deprecated in iOS 13.0