Clickable Tinder Style Cards SwiftUI

I'm trying to create a swipeable shopping app prototype and came across a problem that I simply can't figure out.

My goal is to make each card clickable, so that when a user taps on one of them, it shows them another view with more product details

I've already made the cards swipeable, and i've already made each card clickable.

I am unable to figure out how to update the information in product view so that it matches with the clicked card

Code Block language
struct ContentView: View {
  // MARK: - PROPERTIES
   
  @EnvironmentObject var shop: Shop
   
  @State var showLiked: Bool = false
  @State var showBag: Bool = false
   
  @GestureState private var dragState = DragState.inactive
  private let dragAreaThreshold: CGFloat = 65.0
  @State private var lastCardIndex: Int = 1
  @State private var cardRemovalTransition = AnyTransition.trailingBotton
   
  // MARK: - CARD VIEWS
   
  @State var cardViews: [CardView] = {
    var views = [CardView]()
    for index in 0..<2 {
      views.append(CardView(zoope: zoopeData[index]))
    }
    return views
  }()
   
  // MARK: - MOVE THE CARD
   
  private func moveCards() {
    cardViews.removeFirst()
     
    self.lastCardIndex += 1
     
    let zoope = zoopeData[lastCardIndex % zoopeData.count]
     
    let newCardView = CardView(zoope: zoope)
     
    cardViews.append(newCardView)
  }
   
  // MARK: - TOP CARD
   
  private func isTopCard(cardView: CardView) -> Bool {
    guard let index = cardViews.firstIndex(where: { $0.id == cardView.id }) else {
      return false
    }
    return index == 0
  }
   
  // MARK: - DRAG STATE
   
  enum DragState {
    case inactive
    case pressing
    case dragging(translation: CGSize)
     
    var translation: CGSize {
      switch self {
      case .inactive, .pressing:
        return .zero
      case .dragging(let translation):
        return translation
      }
    }
     
    var isDragging: Bool {
      switch self {
      case .dragging:
        return true
      case .pressing, .inactive:
        return false
      }
    }
     
    var isPressing: Bool {
      switch self {
      case .pressing, .dragging:
        return true
      case .inactive:
        return false
      }
    }
  }
   
  var body: some View {
    VStack {
      if shop.showingProduct == false && shop.selectedProduct == nil {
        ZStack {
        Color("ColorBackground")
          .ignoresSafeArea(edges: .all)
        VStack {
          // MARK: - HEADER
          HeaderView()
          Spacer()
           
          // MARK: - CARDS
          ZStack {             
            ForEach(cardViews) { cardView in
              cardView
                .zIndex(self.isTopCard(cardView: cardView) ? 1 : 0)
                .onTapGesture {
                  shop.selectedProduct = sampleClothes
                  shop.showingProduct = true
                }
                .overlay(
                  ZStack {
                    // X-MARK SYMBOL
                    Image(systemName: "x.circle")
                      .modifier(SymbolModifier())
                      .opacity(self.dragState.translation.width < -self.dragAreaThreshold && self.isTopCard(cardView: cardView) ? 1.0 : 0.0)
                     
                    // HEART SYMBOL
                    Image(systemName: "heart.circle")
                      .modifier(SymbolModifier())
                      .opacity(self.dragState.translation.width > self.dragAreaThreshold && self.isTopCard(cardView: cardView) ? 1.0 : 0.0)
                  }
                )
                 
                .offset(x: self.isTopCard(cardView: cardView) ? self.dragState.translation.width : 0, y: self.isTopCard(cardView: cardView) ? self.dragState.translation.height : 0)
                .scaleEffect(self.dragState.isDragging && self.isTopCard(cardView: cardView) ? 0.85 : 1.0)
                .rotationEffect(Angle(degrees: self.isTopCard(cardView: cardView) ? Double(self.dragState.translation.width / 12) : 0))
                .animation(.interpolatingSpring(stiffness: 120, damping: 120))
                .gesture(LongPressGesture(minimumDuration: 0.01)
                      .sequenced(before: DragGesture())
                      .updating(self.$dragState, body: { (value, state, transaction) in
                        switch value {
                        case .first(true):
                          state = .pressing
                        case .second(true, let drag):
                          state = .dragging(translation: drag?.translation ?? .zero)
                        default:
                          break
                        }
                      })
                      .onChanged({ (value) in
                        guard case .second(true ,let drag?) = value else {
                          return
                        }
                         
                        if drag.translation.width < -self.dragAreaThreshold {
                          self.cardRemovalTransition = .leadingBottom
                        }
                         
                        if drag.translation.width > self.dragAreaThreshold {
                          self.cardRemovalTransition = .trailingBotton
                        }
                      })
                      .onEnded({ (value) in
                        guard case .second(true, let drag?) = value else {
                          return
                        }
                         
                        if drag.translation.width < -self.dragAreaThreshold || drag.translation.width > self.dragAreaThreshold {
                          self.moveCards()
                        }
                      })
                ).transition(self.cardRemovalTransition)
            }
          }
          .padding()
           
          Spacer()
           
          // MARK: - FOOTER
          FooterView(showLikedView: $showLiked, showBagView: $showBag)
            .opacity(dragState.isDragging ? 0.0 : 1.0)
            .animation(.default)
        }
           
        }
      } else {
        ProductDetailView()
      }
    }
  }
}

The problem lies in 
Code Block
shop.selectedProduct = sampleClothes

I can't use
Code Block
cardView
as they are different data types

Any help/suggestions would be greatly appreciated, as I have tried literally everything I could think of over the past 3 days to solve this.

P.S- i can provide more code if needed. apologies for the long pasted code
How is selectedProduct defined ? In fact, how is Shop defined ?

How is sampleClothes defined ?

Maybe you need to declare as AnyView.
But would need to see the declarations.
Your code contains many missing parts -- Shop, AnyTransition.trailingBotton, CardView, zoopeData, ProductDetailView and sampleClothes, or possibly more.

If you could show buildable, simplified, but enough to reproduce the issue, I (and many readers) would examine it.


One thing to note, having Views in an @State variable would be a bad design in SwiftUI in almost all cases. Just hold a model enough to represent CardView, and construct CardView inside body using the model.
Clickable Tinder Style Cards SwiftUI
 
 
Q