I created a view which displays a stack of cards. I am passing two parameters to it:
struct CardStack: View {
var cards: [Card]
var content: (Int, Card) -> CardView
init(cards: [Card], @ViewBuilder content: @escaping (Int, Card) -> CardView) {
self.cards = cards
self.content = content
}
var body: some View {
ZStack {
ForEach(Array(cards.enumerated()), id: \.element.id) { index, card in
content(index, card)
}
}
}
}
It works fine when the closure contains just the CardView, but as soon as I add any view modifier to the CardView (and I need to add many of them), the returned type of the closure changes to some View
, and I get an error: Cannot convert return expression of type 'some View' to return type 'CardView'
var deckBody: some View {
CardStack(cards: viewModel.cards) { index, card in // Error: Cannot convert return expression of type 'some View' to return type 'CardView'
CardView(card: card)
.zIndex(Double(index))
}
}
Then, when I amend CardView to expect a closure returning any View
instead of the CardView
, I get another error Static method 'buildExpression' requires that 'Content' conform to 'AccessibilityRotorContent'
:
struct CardStack: View {
var cards: [Card]
var content: (Int, Card) -> any View
init(cards: [Card], @ViewBuilder content: @escaping (Int, Card) -> any View) {
self.cards = cards
self.content = content
}
var body: some View {
ZStack {
ForEach(Array(cards.enumerated()), id: \.element.id) { index, card in
content(index, card) // Error: Static method 'buildExpression' requires that 'Content' conform to 'AccessibilityRotorContent'
}
}
}
}
Why should I, and how can I make the closure conform to 'AccessibilityRotorContent'?
CardStack
should have a generic type parameter indicating the type of View
that each card is displayed as.
struct CardStack<CardContent: View>: View {
var cards: [Card]
var content: (Int, Card) -> CardContent
init(cards: [Card], @ViewBuilder content: @escaping (Int, Card) -> CardContent) {
self.cards = cards
self.content = content
}
...
}