Hi
I'm trying to make an app which has card lists using TCA.
The cards can be removed or inserted by action.
But, not as MVVM, my cards transition methods doesn't work.
Here's my example
// App.swift
import SwiftUI
import ComposableArchitecture
struct AppState: Equatable {
var cards: [Card] = (10...20).map { Card(id: $0, number: $0) }
}
enum AppAction {
case cardCompleted(Int)
case removeCard(Int)
case getNewCards
}
struct AppEnvironment {
var mainQueue: AnySchedulerOf<DispatchQueue> = DispatchQueue.main.eraseToAnyScheduler()
}
let appReducer = Reducer<AppState, AppAction, AppEnvironment> { state, action, env in
switch action {
case .cardCompleted(let id):
guard let card = state.cards.filter({ $0.id == id }).first,
let index = state.cards.firstIndex(of: card) else {
return .none
}
state.cards[index].status = .completed
return Effect.init(value: AppAction.removeCard(index))
.delay(for: 2, scheduler: env.mainQueue)
.eraseToEffect()
case .removeCard(let index):
state.cards.remove(at: index)
return Effect.init(value: AppAction.getNewCards)
.delay(for: 0.1, scheduler: env.mainQueue)
.eraseToEffect()
case .getNewCards:
state.cards = (0...9).map { Card(id: $0, number: $0) }
return .none
}
}
struct AppView: View {
let store: Store<AppState, AppAction>
var body: some View {
WithViewStore(self.store) { viewStore in
ScrollView(.horizontal) {
HStack(spacing: 20) {
ForEach(viewStore.cards) { card in
CardView(card: card)
.onTapGesture {
viewStore.send(.cardCompleted(card.id))
}
}
}
}
}
}
}
// Card.swift
import SwiftUI
enum CardStatus {
case none
case completed
}
struct Card: Equatable, Identifiable {
var id: Int
var number: Int
var status: CardStatus = .none
}
struct CardView: View {
let card: Card
var body: some View {
VStack {
Text("Hello Card")
Text("\(card.number)")
}
.frame(width: 100, height: 150)
.background(Color.yellow)
// this part doensn't work
.transition(.asymmetric(
insertion: AnyTransition.move(edge: .trailing),
removal: AnyTransition.move(edge: .bottom)))
}
}
struct CardView_Previews: PreviewProvider {
static var previews: some View {
CardView(card: Card(id: 0, number: 0))
}
}
What I want is applying animation before removal and new card insertion after removal.
It would be nice if you let me know the solution and some knowledges about the relationship between SwiftUI and TCA(I mean, why my example didn't work).
Thanks for your help
I resolve this by adding .animation(.default).