Skip to content

Instantly share code, notes, and snippets.

@huynguyencong
Created September 30, 2022 07:44
Show Gist options
  • Save huynguyencong/dba966491136537343f70cd3a2464cf2 to your computer and use it in GitHub Desktop.
Save huynguyencong/dba966491136537343f70cd3a2464cf2 to your computer and use it in GitHub Desktop.
Measure a view size with GeometryReader but doesn't take all spaces from parent view
import SwiftUI
struct MeasurementModifier: ViewModifier {
@Binding var isEnabled: Bool
let sizeChanged: (CGSize) -> Void
func body(content: Content) -> some View {
content.background(MeasurementView(isEnabled: $isEnabled, sizeChanged: sizeChanged))
}
struct MeasurementView: View {
@State private var size: CGSize = .zero
@Binding var isEnabled: Bool
let sizeChanged: (CGSize) -> Void
var body: some View {
return GeometryReader { geo in
if size != geo.size && isEnabled {
DispatchQueue.main.async {
self.isEnabled = false
self.size = geo.size
sizeChanged(geo.size)
}
}
return Text("")
}
}
}
}
extension View {
func measure(isEnabled: Binding<Bool>, sizeChanged: @escaping (CGSize) -> Void) -> some View {
modifier(MeasurementModifier(isEnabled: isEnabled, sizeChanged: sizeChanged))
}
}
import SwiftUI
struct ContentView: View {
@State private var size: CGSize = .zero
@State private var text: String = ""
@State private var isMeasurmentEnabled = true
var body: some View {
VStack {
Text("Size: \(size.width), \(size.height)")
Text(text)
.background {
Color.green
}
TextField("Input here", text: $text)
.border(Color.black)
}
.measure(isEnabled: $isMeasurmentEnabled) { size in
self.size = size
isMeasurmentEnabled = true
}
.border(Color.blue)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment