I want to to know how can I count my inPutView
in this example of code, the code working like this, it takes some views and gave a background color and counts the count of view, thanks for help.
struct ContentView: View {
var body: some View {
ModelView(inputView: {
Text("Hello, world!").padding()
Text("Hello, world!").padding()
})
}
}
struct ModelView<Content: View>: View {
var inPutView: () -> Content
init(@ViewBuilder inputView: @escaping () -> Content) { self.inPutView = inputView }
var body: some View {
VStack {
inPutView()
}
.background(Color.green)
Text("count of inPutViews: 2").padding() // Here: How can I found out the count of inPutView?
}
}
update:
struct ContentView: View {
var inputViews: [AnyView] = [AnyView(Text("Hello, world!").padding()), AnyView(Text("Hello, world!").padding())]
var body: some View {
ModelView2(inputViews: inputViews)
}
}
struct ModelView2: View {
var inputViews: [AnyView]
var body: some View {
VStack {
ForEach(inputViews.indices, id:\.self) { index in
inputViews[index]
}
}
.background(Color.green)
Text("count of inPutViews: \(inputViews.count)")
.padding()
}
}
It's not possible to detect the count if individual views inside a @ViewBuilder
closure. The @ViewBuilder
creates one resulting view and your inPutView
is treated as a single view.
A possible solution is to pass the [AnyView]
array as the input of ModelView
. But then AnyView
doesn't conform to Hashable
nor Identifiable
, so you can't use it in a ForEach
.
In your case you can create a separate struct conforming to Identifiable
:
struct AnyViewItem: Identifiable {
let id = UUID()
let view: AnyView
}
and populate ModelView
with an array of AnyViewItem
:
struct ModelView: View {
var inputViews: [AnyViewItem]
var body: some View {
VStack {
ForEach(inputViews) {
$0.view
}
}
.background(Color.green)
Text("count of inPutViews: \(inputViews.count)")
.padding()
}
}
Then, you can use it in your main view like this:
struct ContentView: View {
var body: some View {
ModelView(
inputViews: [
Text("Hello, world!").padding(),
Text("Hello, world!").padding(),
]
.map {
AnyViewItem(view: AnyView($0))
}
)
}
}
Alternatively, as suggested in the comments, in this case you can make inputViews
an [AnyView]
array and iterate through its indices
:
ForEach(inputViews.indices, id: \.self) {
inputViews[$0]
}