Skip to content

Instantly share code, notes, and snippets.

@BrentMifsud
Last active February 16, 2023 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BrentMifsud/84dca10335e17a2c4086c20135a478f5 to your computer and use it in GitHub Desktop.
Save BrentMifsud/84dca10335e17a2c4086c20135a478f5 to your computer and use it in GitHub Desktop.
View Modifier that will fetch a SwiftUI view's safe area inset and expose it via the preferences system.
import SwiftUI
public extension View {
func onSafeAreaChange(onChange: @escaping (EdgeInsets) -> Void) -> some View {
modifier(SafeAreaReader(onChange: onChange))
}
}
internal struct SafeAreaReader: ViewModifier {
var onChange: (EdgeInsets) -> Void
func body(content: Content) -> some View {
content
.background(
GeometryReader { proxy in
Color.clear
.preference(key: SafeAreaPreferenceKey.self, value: proxy.safeAreaInsets)
}
// For some reason, preference changes are lost after leaving the background modifier.
// Maybe the background modifier contains its own separate view hierarchy?
.onPreferenceChange(SafeAreaPreferenceKey.self, perform: onChange)
)
}
}
internal struct SafeAreaPreferenceKey: PreferenceKey {
public static var defaultValue: EdgeInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
public static func reduce(value: inout EdgeInsets, nextValue: () -> EdgeInsets) {
value = nextValue()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment