階層が一番上のViewのSafe Areaの情報を知りたい時があったので備忘録として残します。
GeometryReaderを使用した場合、そのViewのSafe Areaの情報しか取得できず、一番上のViewのSafe Areaの情報が取得できません。そこで今回はEnvironmentを使ってどのViewでも一番上のViewのSafe Area Insetsを取得できるEnvironmentを自作していきます。
実装
まずはUIApplicationからkeyWindowを取得できるプログラムを記述していきます。
public extension UIApplication {
var keyWindow: UIWindow? {
connectedScenes
.compactMap { $0 as? UIWindowScene }
.first?
.windows
.filter(\.isKeyWindow)
.first
}
}
ちなみにkeyWindowは直近でmakeKeyAndVisible()メソッドを実行した最新のUIWindowを指します。つまり、アプリの最前面にあるWindowです。
次にUIEdgeInsetsからEdgeInsetsに変換するコードを記述していきます。
extension UIEdgeInsets {
var edgeInsets: EdgeInsets {
EdgeInsets(top: top, leading: left, bottom: bottom, trailing: right)
}
}
さいごにEnvironmentKeyを定義し、EnvironmentValuesにpropertyを生やします。
private struct SafeAreaInsetsKey: EnvironmentKey {
static var defaultValue: EdgeInsets {
UIApplication.shared.keyWindow?.safeAreaInsets.edgeInsets ?? EdgeInsets()
}
}
public extension EnvironmentValues {
var safeAreaInsets: EdgeInsets {
self[SafeAreaInsetsKey.self]
}
}
使用方法
struct HogeView: View {
@Environment(\.safeAreaInsets) var safeAreaInsets
var body: some View {
Text("ステータスバーの高さは\(safeAreaInsets.top)です")
}
}
このようにして一番上のViewのSafe Area Insetsを取得することができました。
参考