Reputation: 1033
I have several shapes names circle1(),circle2(),circle3(), up to circle20() all with slightly different attributes. How can I use forEach in the same way that I could use string interpolation to loop through all of them.
ForEach(0..<20){ i in
Image("circle\(i)").offset(x:CGFloat(i * 100),y:0)
}
The above example is for an image and it works fine, but would there be a way to do the same with similar named shapes? Of course the following example below didn't work:
ForEach(0..<20){ i in
circle\(i).offset(x:CGFloat(i * 100),y:0)
}
Upvotes: 0
Views: 862
Reputation: 36304
if you really need to use shape names, maybe something like this:
struct MyShape {
var name: String
var shape: AnyView
}
struct ContentView: View {
@State var shapes = [
MyShape(name: "circle0", shape: AnyView(Circle())),
MyShape(name: "circle1", shape: AnyView(Rectangle())),
MyShape(name: "circle2", shape: AnyView(Circle())),
MyShape(name: "circle3", shape: AnyView(Rectangle())),
MyShape(name: "circle4", shape: AnyView(Circle()))]
var body: some View {
Group {
ForEach(0..<5) { i in
self.getShapeByName("circle" + String(i)).offset(x: CGFloat(i * 10), y:100)
}
}
}
func getShapeByName(_ name: String) -> AnyView {
if let theShape = shapes.first(where: { $0.name == name }) {
return theShape.shape
}
return AnyView(EmptyView())
}
}
Upvotes: 1
Reputation: 36304
you could try something like this, and coupled with using .tag() instead of array index, could get you what you're after.
@State var shapes = [AnyView]()
var body: some View {
Group {
ForEach(0..<self.shapes.count, id: \.self) { i in
self.shapes[i].offset(x: CGFloat(i * 10), y:100)
}
}.onAppear(perform: loadShapes)
}
func loadShapes() {
for i in 0..<10 {
shapes.append(AnyView(Circle()))
}
for i in 0..<10 {
shapes.append(AnyView(Rectangle()))
}
}
Upvotes: 0