How to create Horizontal swipe card, Right card swipe remove card and left swipe card index append in UIkit
class SwipeCardComponentVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var collectionView: UICollectionView!
var dataSource = ["Card 1", "Card 2", "Card 3", "Card 4", "Card 5"] // Example data source
var removedCards: [(card: String, indexPath: IndexPath)] = [] // To store removed cards for undo
override func viewDidLoad() {
super.viewDidLoad()
// Configure the custom layout
let layout = TinderLayout()
collectionView.collectionViewLayout = layout
collectionView.dataSource = self
collectionView.delegate = self
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
collectionView.addGestureRecognizer(panGesture)
}
// Collection view data source methods
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SwipeCardCell", for: indexPath) as! SwipeCardCell
let color = ["DBA979","BACD92","9BB0C1","8E7AB5","80BCBD","C3E2C2","AFC8AD","D2E0FB"]
cell.bgView.backgroundColor = hexStringToUIColor(hex: String.getString(color[indexPath.row]))
return cell
}
@objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
let location = gesture.location(in: collectionView)
guard let indexPath = collectionView.indexPathForItem(at: location),
let cell = collectionView.cellForItem(at: indexPath) as? SwipeCardCell else {
return
}
let translation = gesture.translation(in: collectionView)
cell.center.x += translation.x // Horizontal movement
gesture.setTranslation(.zero, in: collectionView)
if gesture.state == .ended {
let threshold: CGFloat = 100 // Define threshold for swipe off
let direction: CGFloat = translation.x > 0 ? 1 : -1
if abs(translation.x) > threshold {
if direction < 0 { // Swipe left to remove
swipeLeftAction(cell, indexPath)
} else { // Swipe right to append
swipeRightAction(cell, indexPath)
}
} else {
// Reset the card's position if not swiped far enough
UIView.animate(withDuration: 0.3) {
cell.center = self.collectionView.center
}
}
}
}
func swipeLeftAction(_ cell: SwipeCardCell, _ indexPath: IndexPath) {
UIView.animate(withDuration: 0.3, animations: {
cell.center.x -= 1000 // Swipe off to the left
}, completion: { _ in
// Store the removed card for potential undo
self.removedCards.append((self.dataSource[indexPath.item], indexPath))
// Remove the card from the data source and collection view
self.dataSource.remove(at: indexPath.item)
self.collectionView.deleteItems(at: [indexPath])
})
}
func swipeRightAction(_ cell: SwipeCardCell, _ indexPath: IndexPath) {
UIView.animate(withDuration: 0.3, animations: {
cell.center.x = self.collectionView.center.x // Reset the position
}, completion: nil)
}
}
//MARK:-----SetCollectionViewFlowLayout----
class TinderLayout: UICollectionViewLayout {
private let itemSize = CGSize(width: 400, height: 600) // Set the size of each card
private let interItemSpacing: CGFloat = 10 // Space between stacked cards
override func prepare() {
super.prepare()
}
override var collectionViewContentSize: CGSize {
guard let collectionView = collectionView else { return .zero }
return collectionView.bounds.size
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let collectionView = collectionView else { return nil }
var attributes: [UICollectionViewLayoutAttributes] = []
let numberOfItems = collectionView.numberOfItems(inSection: 0)
// Keep the original order to ensure the first item is on top
for index in 0.. UICollectionViewLayoutAttributes? {
guard let collectionView = collectionView else { return nil }
let attr = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attr.size = itemSize
let center = collectionView.center
attr.center = CGPoint(x: center.x, y: center.y)
// Adjust position for overlapping effect
attr.transform = CGAffineTransform(translationX: 0, y: -CGFloat(indexPath.item) * interItemSpacing)
return attr
}
}
not working properly please help