How can I get the safeAreaInsets in iOS 15?

In the past, I use UIApplication.shared.windows.first?.safeAreaInsets.bottom to get the bottom safe area, but in iOS 15, there is an warning shows that windows has been deprecated. My project is written in SwiftUI, so is there a way to get the global safeAreaInsets again and fits iOS 15?

Accepted Reply

The problem with your code is that you could be selecting any window, including one that is offscreen, private to the system, or otherwise incorrect for your needs, which is why UIKit deprecated the UIApplication level window list.

If you have a UIView in your UI, you can obtain the window from that view, and request its safe area insets.

  • As I mentioned before, my project is written completely in SwiftUI, so how can I get the global safeAreaInsets? Because there is no UIViewController or UIView in my code.

  • You're better off accessing the Safe Area from SwiftUI directly, by using the GeometryReader.

Add a Comment

Replies

The problem with your code is that you could be selecting any window, including one that is offscreen, private to the system, or otherwise incorrect for your needs, which is why UIKit deprecated the UIApplication level window list.

If you have a UIView in your UI, you can obtain the window from that view, and request its safe area insets.

  • As I mentioned before, my project is written completely in SwiftUI, so how can I get the global safeAreaInsets? Because there is no UIViewController or UIView in my code.

  • You're better off accessing the Safe Area from SwiftUI directly, by using the GeometryReader.

Add a Comment

I just had this problem and solved it by changing:

UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.safeAreaInsets ?? .zero

to

UIApplication.shared.connectedScenes.filter({$0.activationState == .foregroundActive}).map({$0 as? UIWindowScene}).compactMap({$0}).first?.windows.filter({$0.isKeyWindow}).first?.safeAreaInsets ?? .zero

Maybe that will help somebody down the line...