I have a stack of cards on screen. I am trying to animate the movement from the stack to positions on a grid. The problem is, when I tap on the stack to move the cards to their positions, the stack disappears. Then the cards fly into place from off screen.
var body: some View {
VStack {
cardStack
testGrid
}
}
//MARK: - TESTING]
@Namespace var testSpace
struct TestCard: Identifiable, View {
init(id: String) {
self.id = id
}
let id: String
let shape = RoundedRectangle(cornerRadius: 10)
var body: some View {
shape
.padding()
}
}
var testDeck: [TestCard] {
var cards = [TestCard]()
for cardIndex in 0..<10 {
let card = TestCard(id: "\(cardIndex)")
cards.append(card)
}
return cards
}
var testGrid: some View {
AspectVGrid(testDeck, aspectRatio: 5 / 3) { card in
if isDealtTest(card) {
TestCard(id: card.id)
.matchedGeometryEffect(id: card.id, in: testSpace)
.transition(.asymmetric(insertion: .identity, removal: .identity))
}
}
}
@State private var dealtTest = Set<TestCard.ID>()
private func isDealtTest(_ card: TestCard) -> Bool {
dealtTest.contains(card.id)
}
private var undealtCardsTest: [TestCard] {
testDeck.filter { !isDealtTest($0) }
}
private var cardStack: some View {
ZStack {
ForEach(undealtCardsTest) { card in
TestCard(id: card.id)
.matchedGeometryEffect(id: card.id, in: testSpace)
.transition(.asymmetric(insertion: .identity, removal: .identity))
}
}
.onTapGesture {
dealTest()
}
}
private func dealTest() {
var delay: TimeInterval = 0
for card in testDeck {
withAnimation(.easeInOut(duration: 1).delay(delay)) {
_ = dealtTest.insert(card.id)
}
delay += 0.15
}
}
I have tried using an array of cards that had nothing to do with my model, as well as cards which did not take an instance of the viewModel. They too disappeared when tapped. These only consisted of a rectangle and an id. I tried moving the position of the deck of cards around the VStack. I used the matchedGeometry and transition to move around a roundedRectangle and had no problem. In another project, I used essentially the same code to move cards from a stack to their positions on a grid.
I think the main issue is that the cards take too much space.
Try setting a maximum size and also aspect ratio on
TestCard
and remove the padding:Then add
.scaledToFit
to the parent container intestGrid
. You might like to add padding too. You didn't provide the implementation ofAspectVGrid
, so I improvised by using anHStack
instead:If you want the cards to go straight to the smaller size, instead of shrinking as more cards are added to the grid, then just apply a fixed size to the cards in
testGrid
: