Search code examples
swiftswiftuixcode11

How to pass variables functions in forEach loops


Goal:

I am currently working on some code to create a grid of hexagons, each one individually coloured with a gradient. However I am quite new to swiftUI and don't fully understand why my code doesn't work.

Code:

ForEach(0 ..< 11, id: \.self) { Xnum in
    ForEach(0 ..< 11, id: \.self) { Ynum in
        self.MyNewPath(in: CGRect(), Xcoord: Double(Xnum), Ycoord: Double(Ynum), Type: 1)
            .fill(RadialGradient(
                gradient: Gradient(colors: [Color.red, Color.blue]),
                center: .init(
                    x: self.gradientParametersX(Xpos: Double(Xnum)),
                    y: self.gradientParametersY(Ypos: Double(Ynum), Xpos: Double(Xnum))),
                startRadius: CGFloat(2.0),
                endRadius: CGFloat(70.0)))
            .gesture(
                TapGesture().onEnded {_ in
                    self.dataEditor(Xplace: Int(Xnum), Yplace: Int(Ynum))
                }
            )
    }
}

Return Types:

  • MyNewPath() - Path (of a hexagon)
  • gradientParametersY() - CGFloat
  • gradientParametersY() - CGFloat

Error:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

The error appears to be centred around the passing of Xnum and Ynum to functions gradientParametersX() and gradientParametersY().

When I pass 7.0 and 0.0 for example:

x: self.gradientParametersX(Xpos: Double(7.0)),
y: self.gradientParametersY(Ypos: Double(0.0), Xpos: Double(7.0))),

...there is no error.


Solution

  • Try to separate grid item creation in separate function as below (the code snapshot is not testable, so just scratchy to demo idea)

        ...
        ForEach(0 ..< 11, id: \.self) { Xnum in
            ForEach(0 ..< 11, id: \.self) { Ynum in
                self.createItem(for: Xnum, Ynum: Ynum)
            }
        }
        ...
    
    private func createItem(for Xnum: Int, Ynum: Int) -> some View {
        self.MyNewPath(in: CGRect(), Xcoord: Double(Xnum), Ycoord: Double(Ynum), Type: 1)
            .fill(RadialGradient(
                gradient: Gradient(colors: [Color.red, Color.blue]),
                center: .init(
                    x: self.gradientParametersX(Xpos: Double(Xnum)),
                    y: self.gradientParametersY(Ypos: Double(Ynum), Xpos: Double(Xnum))),
                startRadius: CGFloat(2.0),
                endRadius: CGFloat(70.0)))
            .gesture(
                TapGesture().onEnded {_ in
                    self.dataEditor(Xplace: Int(Xnum), Yplace: Int(Ynum))
                }
            )
    }