How is it possible to set a @State var inside a geometryReader?
This is my code:
@State var isTest:Int = 0
var body: some View {
VStack{
ForEach(self.test, id: \.id) { Test in
VStack{
GeometryReader { geometry in
self.isTest = 1
I try with a function but it doesn't work.
@State var isTest: Int = 0
func testValue() {
self.isTest = 1
}
var body: some View {
VStack{
ForEach(self.test, id: \.id) { Test in
VStack{
GeometryReader { geometry in
testValue()
Any idea? Thanks!
You can use onGeometryChange(for:of:action:) with Xcode 16.0+ targeting iOS 16.0+ or macOS 13.0+:
struct MyView: View {
@State private var size: CGSize = .zero
var body: some View {
ZStack {
Text("Hello World")
}
.onGeometryChange(for: CGSize.self) { proxy in
proxy.size
} action: { newSize in
size = newSize
}
}
}
You can use onAppear(perform:) to update @State variables with the initial view size and onChange(of:perform:) to update the variables when the view size changes:
struct MyView: View {
@State private var size: CGSize = .zero
var body: some View {
GeometryReader { geometry in
ZStack {
Text("Hello World")
}.onAppear {
size = geometry.size
}.onChange(of: geometry.size) { newSize in
size = newSize
}
}
}
}
While putting code into function is a nice touch, there may arrive another problem and that is altering the @State variable during update phase:
[SwiftUI] Modifying state during view update, this will cause undefined behavior
Using NotificationCenter to move @State variable update after view update phase can help, but one could use much more simple solution like performing variable update right after render phase by using DispatchQueue.
@State var windowSize = CGSize()
func useProxy(_ geometry: GeometryProxy) -> some View {
DispatchQueue.main.async {
self.windowSize = geometry.size
}
return EmptyView()
}
var body: some View {
return GeometryReader { geometry in
self.useProxy(geometry)
Text("Hello SwiftUI")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With