Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define variables inside a GeometryReader in SwiftUI

Tags:

swift

swiftui

I'd like to calculate the line width of a shape inside a view based on the view's size. Looking through various posts here on StackOverflow, I think the solution is to use a GeometryReader like this:

struct MyView: View {
    var body: some View {
        GeometryReader { geometry in
           // Here goes your view content,
           // and you can use the geometry variable
           // which contains geometry.size of the parent
           // You also have function to get the bounds
           // of the parent: geometry.frame(in: .global)
        }
    }
}

My question is, how can I define variables inside the GeometryReader construct to be used for the view? I've tried to put a var statement directly after the line "GeometryReader { geometry in", but this gives a compiler error.

like image 435
G. Marc Avatar asked Jul 16 '19 21:07

G. Marc


People also ask

How do I declare a variable in SwiftUI?

In SwiftUI, you can set up a binding to a variable and then name it as a parameter when you call the struct containing the link. This works but doesn't scale well. Try adding a dozen parameters to your code and it'll quickly become unreadable.

What is a GeometryReader in SwiftUI?

GeometryReader is an special container view like any other container view such as VStack, ZStack and Group but the special part is, the closure this container has, have an parameter of type GeometryProxy with contains information about this containers size and safeAreaInsets , also it has an function frame(in: ...


1 Answers

This seems to be a function builder related bug (as of Beta 3), and I recommend filing feedback on it.

The workaround I've been using is to use GeometryProxy in a separate method with an explicit return.


var body: some View {
  GeometryReader { proxy in
    self.useProxy(proxy)
  }
}

func useProxy(_ proxy: GeometryProxy) -> some View {
  var width = proxy.size.width
  return VStack {
    // use width in here
  }
}
like image 180
arsenius Avatar answered Jan 04 '23 05:01

arsenius