Skip to content

Instantly share code, notes, and snippets.

@emma-k-alexandra
Created January 17, 2022 21:11
Show Gist options
  • Save emma-k-alexandra/238b87c0b990c740e97930fe2061ae12 to your computer and use it in GitHub Desktop.
Save emma-k-alexandra/238b87c0b990c740e97930fe2061ae12 to your computer and use it in GitHub Desktop.
Assign the size of a SwiftUI View to a Binding - Based on Federico Zanetello's `readSize`
import SwiftUI
/*
Example
struct MyView: View {
@State private var childSize = CGSize.zero
var body: some View {
ChildView()
.assignSize(to: $childSize)
}
}
*/
extension View {
func assignSize(to binding: Binding<CGSize>) -> some View {
readSize { size in
binding.wrappedValue = size
}
}
}
// From Federico's original work
// Gist: https://github.com/FiveStarsBlog/CodeSamples/blob/main/SwiftUI-read-a-view-size/View+readSize.swift
// Explainer blog post: https://fivestars.blog/articles/swiftui-share-layout-information/
struct SizePreferenceKey: PreferenceKey {
static var defaultValue = CGSize.zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
extension View {
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {
background(
GeometryReader { geometryProxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometryProxy.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
}
/*
Example:
var body: some View {
childView
.readSize { newSize in
print("The new child size is: \(newSize)")
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment