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/33c4d426fe60a36ba605ed277c0790e2 to your computer and use it in GitHub Desktop.
Save BrentMifsud/33c4d426fe60a36ba605ed277c0790e2 to your computer and use it in GitHub Desktop.
A SwiftUI ViewModifier that reads a view's size
import SwiftUI
public extension View {
/// Exposes the size of the specified view
/// - Parameter onChange: This function will be called when the size of a view changes.
/// - Returns: some View
func onSizeChange(onChange: @escaping (CGSize) -> Void) -> some View {
modifier(SizeReader(onChange: onChange))
}
}
internal struct SizeReader: ViewModifier {
var onChange: (CGSize) -> Void
func body(content: Content) -> some View {
content
.background(
GeometryReader { proxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: proxy.size)
}
// For some reason, preference changes are lost after leaving the background modifier.
// Maybe the background modifier contains its own separate view hierarchy?
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
)
}
}
internal struct SizePreferenceKey: PreferenceKey {
public static var defaultValue: CGSize = .zero
public static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment