Skip to content

Instantly share code, notes, and snippets.

@darrarski
Last active February 14, 2024 17:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrarski/61220224c4b2b15af127fa4159d2d60b to your computer and use it in GitHub Desktop.
Save darrarski/61220224c4b2b15af127fa4159d2d60b to your computer and use it in GitHub Desktop.
Swift UI vie modifier for retrieving the view size
import SwiftUI
public extension View {
func onSizeChange(
ignoreSafeArea: Bool = false,
round: Bool = false,
perform action: @escaping (CGSize) -> Void
) -> some View {
modifier(SizeChangeModifier(
ignoreSafeArea: ignoreSafeArea,
round: round,
onSizeChange: action
))
}
}
private struct SizeChangeModifier: ViewModifier {
var ignoreSafeArea: Bool
var round: Bool
var onSizeChange: (CGSize) -> Void
func body(content: Content) -> some View {
content
.background(
GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self, value: size(from: geometry))
.onPreferenceChange(SizePreferenceKey.self, perform: onSizeChange)
}
)
}
func size(from proxy: GeometryProxy) -> CGSize {
var size = proxy.size
if ignoreSafeArea {
size.width += proxy.safeAreaInsets.leading + proxy.safeAreaInsets.trailing
size.height += proxy.safeAreaInsets.top + proxy.safeAreaInsets.bottom
}
if round {
size.width = size.width.rounded()
size.height = size.height.rounded()
}
return size
}
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
}
// MARK: - Example
struct ExampleView: View {
var body: some View {
Text("Hello, World")
.onSizeChange { size in
print("size of the view = \(size)")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment