I'm trying to make an array of Views so that, ideally, each element of the array can have a different composition of child View elements. I have tried to achieve this by creating an array of [some View]
. Apparently the compiler inspects the first element of the the array upon initializing the array and expects all elements have a similar composition of subviews. I'd appreciate any help to get around this problem or an alternative solution.
In the simplest form I have created an array of [some View]
with two VStack elements, yet each VStack contains two subviews, a Text and an Image with different layout order.
var myArray : [some View] = [
VStack{
Text("foo")
Image("foo_image")
},
VStack{
Image("bar_image")
Text("bar")
}
]
Apparently the compiler infers the type of array as () -> TuppleView<Text,Image>
by evaluating the first element and complains that the second element is of type () -> TuppleView<Image,Text>
can not be converted to the aforesaid type.
My question is that whether there is a way to hide the detail of the containing Views or wrap it in an opaque object so that I can create an array of Views with different elements and layout arrangements.
Here is a minimal reproducible example
struct WrapperView <Content : View> : View , Identifiable{
var id: String
let content : Content
var body: some View{
VStack{
Text("Some text")
content
}
}
init(id : String , @ViewBuilder content : ()-> Content){
self.id = id
self.content = content()
}
}
struct TheItemList {
static var theItems : [WrapperView< some View>] = [
WrapperView(id : "frist one" , content: {
HStack{
Text("foo")
Image(systemName: "heart")
}
}),
WrapperView(id : "second one" , content: {
HStack{
Image(systemName: "bolt")
Text("bar")
}
})
]
}
struct TestView : View {
var body: some View{
ScrollView{
ForEach(TheItemList.theItems , id: \.id){item in
item
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
Obviously everything is fine when the order of Text and Image elements in the second HStack matches the first one's.