Reference data from collection data in one ViewModel as another ViewModels data

40 Views Asked by At

I currently have 2 classes. One of them is named DeckManager and holds Deck objects inside an Array collection named decks (Each Deck contains an array of Card objects).
The next Class is named FlashcardGame has an Array collection that stores CardObjects.
Within my HomeView I am using ForEach on the DeckManager.decks collection and for each deck would be a NavigationLink. This Navigation link would then take the user to FlashcardGameView which utilizes FlashcardGameViewModel. I am trying to have the cards property inside FlashcardGameVM to reference the Deck that the user selects to navigate to the game.

I tried utilizing ARC (Automatic reference counting), and introducing Strong, and weak referencing but having difficulties finding resources that would help me in this scenario. The FlashcardGameView is simply a Game that references the data it would not be making changes to the underlying data. Any feedback is welcome.

class DeckManager: ObservableObject {
    @Published var decks: [Deck] = []
    @Published var inProgressDeck: Deck

    init() {
        self.inProgressDeck = Deck(cards: [Card()])
        self.decks = Deck(cards: [Card(),Card(), Card()])
    }

Currently I have in my init below cards reflecting sample data. I want it to reflect the cards within the selected Deck for navigation into the FlashcardGameView.

class FlashcardGameVM: ObservableObject {
   
    @Published var cards: [Card]
    @Published var currentCard: Card { didSet {
        backDegree = -90.0
        frontDegree = 0.0
        }
    }
    @Published var randomAnswers: [String] = []
    @Published var backDegree = -90.0 // Make it optional
    @Published var frontDegree: Double = 0.0
    let durationAndDelay : CGFloat = 0.5
    
    init() {
        let cards = CardManager.cards
        self.cards = cards
        self.currentCard = cards.first! // FORCE UNWRAP DUE TO CARD ALWAYS BEING AVAILABLE TO PLAY GAME.
        
    }
    
    
    func switchCard() {
        // Get current index
        guard let currentIndex = cards.firstIndex(where: { $0 == currentCard }) else {
            print("Could not find current Index SHOULD NEVER HAPPEN!")
            return
        }
        // check if currentIndex is valid
        let nextIndex = currentIndex + 1
        guard cards.indices.contains(nextIndex) else {
            // next index is NOT valid
            // restart from 0
            guard let firstCard = cards.first else { return }
            showNextLocation(card: firstCard)
            return
        }
        // if next index is valid
        let nextLocation = cards[nextIndex]
        showNextLocation(card: nextLocation)
       
    }
    

struct HomeView: View {
     @ObservedObject var deckManager: DeckManager

 private var decksContent: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack(spacing: 15) {
                ForEach(deckManager.itemCollection) { deck in
                    NavigationLink {
                        // FlashcardGameView pass deck here?
                    } label: {
                        DeckView(deck: deck)
                    }

**The Game View ---**


struct FlashcardGameView: View {
    @StateObject private var flashcardGameVM = FlashcardGameVM()
    @State private var answerState: [String : AnswerState] = [:]
    @State private var cardOffset: CGFloat = 400
    @State var answerOpacityAnimate = false
    @State private var shake = false
    
    var body: some View {
        ZStack {
            Color.clear.ignoresSafeArea()
            
            VStack {
                ForEach(flashcardGameVM.cards) { card in
                    if flashcardGameVM.currentCard == card {
                        VStack {
                            FlashcardView(flashcardGame: flashcardGameVM)
                                .offset(x: cardOffset)
                                .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
                                .animation(.spring(), value: flashcardGameVM.currentCard)
                            
0

There are 0 best solutions below