Post

Replies

Boosts

Views

Activity

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 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  shop.selectedProduct = sampleClothes I can't use cardViewas 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
2
0
1.1k
Feb ’21