{"id":2542,"url":"https://github.com/JoniVR/VerticalCardSwiper","last_synced_at":"2025-08-06T16:31:03.388Z","repository":{"id":45265537,"uuid":"99737934","full_name":"JoniVR/VerticalCardSwiper","owner":"JoniVR","description":"A marriage between the Shazam Discover UI and Tinder, built with UICollectionView in Swift.","archived":false,"fork":false,"pushed_at":"2023-10-02T02:43:50.000Z","size":1780,"stargazers_count":1403,"open_issues_count":15,"forks_count":101,"subscribers_count":20,"default_branch":"main","last_synced_at":"2024-12-06T22:51:30.360Z","etag":null,"topics":["animation","cards","collectionview","discover","help-wanted","ios","shazam","shazam-discover-ui","swift","swipe","tinder","tinder-style","tinder-ui","uicollectionview","uikit"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoniVR.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-08-08T21:32:32.000Z","updated_at":"2024-12-06T08:20:15.000Z","dependencies_parsed_at":"2024-01-02T21:25:10.203Z","dependency_job_id":null,"html_url":"https://github.com/JoniVR/VerticalCardSwiper","commit_stats":{"total_commits":189,"total_committers":10,"mean_commits":18.9,"dds":"0.22751322751322756","last_synced_commit":"669694f17d9038cb9e3301221a67c6549b6dd380"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoniVR%2FVerticalCardSwiper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoniVR%2FVerticalCardSwiper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoniVR%2FVerticalCardSwiper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoniVR%2FVerticalCardSwiper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoniVR","download_url":"https://codeload.github.com/JoniVR/VerticalCardSwiper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228923687,"owners_count":17992566,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","cards","collectionview","discover","help-wanted","ios","shazam","shazam-discover-ui","swift","swipe","tinder","tinder-style","tinder-ui","uicollectionview","uikit"],"created_at":"2024-01-05T20:16:16.379Z","updated_at":"2024-12-09T16:31:00.568Z","avatar_url":"https://github.com/JoniVR.png","language":"Swift","funding_links":[],"categories":["UI","Libs","Cards","Swift","HarmonyOS","UI [🔝](#readme)","Content"],"sub_categories":["Cards","UI","Windows Manager"],"readme":"\u003ch1 align=\"center\"\u003e VerticalCardSwiper \u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n    A marriage between the Shazam Discover UI and Tinder, built with UICollectionView in Swift.\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003c!-- build status --\u003e\n    \u003ca href=\"https://github.com/JoniVR/VerticalCardSwiper/actions\"\u003e\n        \u003cimg src=\"https://github.com/JoniVR/VerticalCardSwiper/workflows/build/badge.svg\" alt=\"build status\"\u003e\n    \u003c/a\u003e\n    \u003c!-- pod version --\u003e\n    \u003ca href=\"https://cocoapods.org/pods/VerticalCardSwiper\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/v/VerticalCardSwiper.svg?style=flat\"  alt=\"cocoapods version\"\u003e\n    \u003c/a\u003e\n    \u003c!-- carthage compatible --\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\"  alt=\"Carthage compatible\"\u003e\n    \u003c/a\u003e\n    \u003c!-- license --\u003e\n    \u003ca href=\"https://github.com/JoniVR/VerticalCardSwiper/blob/master/LICENSE\"\u003e\n        \u003cimg alt=\"GitHub\" src=\"https://img.shields.io/github/license/JoniVR/VerticalCardSwiper.svg\"\u003e\n    \u003c/a\u003e\n    \u003c!-- platform --\u003e\n    \u003ca href=\"https://cocoapods.org/pods/VerticalCardSwiper\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/p/VerticalCardSwiper.svg?style=flat?\" alt=\"platform\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://swift.org/blog/swift-5-released/\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/swift-5.0-brightgreen.svg\" alt=\"swift5.0\"\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n  \n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./example.gif\" alt=\"example\"\u003e\n\u003c/div\u003e\n\n## Project goal and information\nThe goal of this project is to recreate the Discover UI in Shazam (which I think is a great, fun way to display content) in combination with a Tinder style of swiping cards to the left/right.\nThe idea behind this is that in some cases, you don't want to swipe away cards, but keep them available for later on. This implementation allows for that. And it's a fun way to interact with content.\n\nIt's built with a `UICollectionView` and a custom flowLayout.\n\n## Requirements\n* iOS 9.0+\n* Swift 5\n\n## Installation\n\n### CocoaPods\nTo install with [CocoaPods](https://cocoapods.org), simply add the following line to your Podfile:\n```ruby\npod 'VerticalCardSwiper'\n```\n\n### Carthage\nTo install with [Carthage](https://github.com/Carthage/Carthage), simply add the following line to your Podfile:\n```ruby\ngithub \"JoniVR/VerticalCardSwiper\"\n```\n\n## Example\nTo try out `VerticalCardSwiper`\n\n```ruby\npod try VerticalCardSwiper\n```\n\nor open the project and run the Example.\n\n## Usage\n`VerticalCardSwiper` behaves a lot like a standard `UICollectionView`. \nTo use it inside your `UIViewController`:\n\n```swift\nimport VerticalCardSwiper\n\nclass ExampleViewController: UIViewController, VerticalCardSwiperDatasource {\n    \n    private var cardSwiper: VerticalCardSwiper!\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        cardSwiper = VerticalCardSwiper(frame: self.view.bounds)\n        view.addSubview(cardSwiper)\n        \n        cardSwiper.datasource = self\n        \n        // register cardcell for storyboard use\n        cardSwiper.register(nib: UINib(nibName: \"ExampleCell\", bundle: nil), forCellWithReuseIdentifier: \"ExampleCell\")\n    }\n    \n    func cardForItemAt(verticalCardSwiperView: VerticalCardSwiperView, cardForItemAt index: Int) -\u003e CardCell {\n        \n        if let cardCell = verticalCardSwiperView.dequeueReusableCell(withReuseIdentifier: \"ExampleCell\", for: index) as? ExampleCardCell {\n            return cardCell\n        }\n        return CardCell()\n    }\n    \n    func numberOfCards(verticalCardSwiperView: VerticalCardSwiperView) -\u003e Int {\n        return 100\n    }\n}\n```\n\n#### Properties\n```swift\n/// Indicates if side swiping on cards is enabled. Set to false if you don't want side swiping. Default is `true`.\n@IBInspectable public var isSideSwipingEnabled: Bool = true\n/// Allows you to enable/disable the stacking effect. Default is `true` (enabled).\n@IBInspectable public var isStackingEnabled: Bool = true\n/// The transform animation that is shown on the top card when scrolling through the cards. Default is 0.05.\n@IBInspectable public var firstItemTransform: CGFloat = 0.05\n/// The inset (spacing) at the top for the cards. Default is 40.\n@IBInspectable public var topInset: CGFloat = 40\n/// The inset (spacing) at each side of the cards. Default is 20.\n@IBInspectable public var sideInset: CGFloat = 20\n/// Sets how much of the next card should be visible. Default is 50.\n@IBInspectable public var visibleNextCardHeight: CGFloat = 50\n/// Vertical spacing between the focussed card and the bottom (next) card. Default is 40.\n@IBInspectable public var cardSpacing: CGFloat = 40\n/// Allows you to set the view to Stack at the Top or at the Bottom. Default is true.\n@IBInspectable public var isStackOnBottom: Bool = true\n/// Sets how many cards of the stack are visible in the background\n@IBInspectable public var stackedCardsCount: Int = 1\n/** \n Returns an array of indexes (as Int) that are currently visible in the `VerticalCardSwiperView`.\n This includes cards that are stacked (behind the focussed card).\n*/\npublic var indexesForVisibleCards: [Int]\n```\n\n#### Other\n##### Just like with a regular `UICollectionView`, you can reload the data by calling\n```swift\ncardSwiper.reloadData()\n```\n\n##### Get the current focussed card index\n```swift\ncardSwiper.focussedCardIndex\n```\n\n##### Scroll to a specifc card by calling\n```swift\ncardSwiper.scrollToCard(at: Int, animated: Bool) -\u003e Bool\n```\n\n##### Get a card at a specified index\n```swift\ncardSwiper.cardForItem(at: Int) -\u003e CardCell?\n```\n\n##### Swipe a card away programatically\n```swift\ncardSwiper.swipeCardAwayProgrammatically(at: Int, to: SwipeDirection, withDuration: TimeInterval = 0.3) -\u003e Bool\n```\n\n##### Moving/Deleting/Inserting cards at runtime\nMake sure to update your datasource first, otherwise an error will occur.\n```swift\ncardSwiper.moveCard(at: Int, to: Int)\ncardSwiper.deleteCards(at: [Int])\ncardSwiper.insertCards(at: [Int])\n```\n\n### Delegation\nTo handle swipe gestures, implement the `VerticalCardSwiperDelegate`.\n\n```swift\nclass ViewController: UIViewController, VerticalCardSwiperDelegate {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        cardSwiper.delegate = self\n    }\n    \n    func willSwipeCardAway(card: CardCell, index: Int, swipeDirection: SwipeDirection) {\n    \n        // called right before the card animates off the screen (optional).\n    }\n\n    func didSwipeCardAway(card: CardCell, index: Int, swipeDirection: SwipeDirection) {\n\n        // handle swipe gestures (optional).\n    }\n    \n    func didCancelSwipe(card: CardCell, index: Int) {\n        \n        // Called when a card swipe is cancelled (when the threshold wasn't reached)\n    }\n    \n    func sizeForItem(verticalCardSwiperView: VerticalCardSwiperView, index: Int) -\u003e CGSize {\n    \n        // Allows you to return custom card sizes (optional).\n        return CGSize(width: verticalCardSwiperView.frame.width * 0.75, height: verticalCardSwiperView.frame.height * 0.75)\n    }\n    \n    func didScroll(verticalCardSwiperView: VerticalCardSwiperView) {\n    \n        // Tells the delegate when the user scrolls through the cards (optional).\n    }\n    \n    func didEndScroll(verticalCardSwiperView: VerticalCardSwiperView) {\n    \n        // Tells the delegate when scrolling through the cards came to an end (optional).\n    }\n    \n    func didDragCard(card: CardCell, index: Int, swipeDirection: SwipeDirection) {\n    \n        // Called when the user starts dragging a card to the side (optional).\n    }\n    \n    func didTapCard(verticalCardSwiperView: VerticalCardSwiperView, index: Int) {\n    \n        // Tells the delegate when the user taps a card (optional).\n    }\n    \n    func didHoldCard(verticalCardSwiperView: VerticalCardSwiperView, index: Int, state: UIGestureRecognizer.State) {\n    \n        // Tells the delegate when the user holds a card (optional).\n    }\n}\n```\n\n### Customization\nSubclass the `CardCell` to customize the cards.\n```swift\nclass ExampleCardCell: CardCell {\n\n}\n```\n\n## Key Features\n- [x] Shazam Discover UI with paging\n- [x] Tinder-style swiping\n- [x] Option to disable side swiping\n- [x] Set custom number of stacked cards\n- [x] Code documentation in README.md file\n- [x] Cocoapods support\n- [x] Carthage support\n- [x] SPM support\n- [ ] Diff support\n\n## Author\nJoni Van Roost, joni.VR@hotmail.com\n\n## License\nVerticalCardSwiper is available under the MIT license. See the LICENSE file for more info.\n\n## More\nFeel free to submit a pull request, open an issue or fork this project. Any help is always appreciated.\nA big thank you to all the [contributors](https://github.com/JoniVR/VerticalCardSwiper/graphs/contributors)! \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJoniVR%2FVerticalCardSwiper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJoniVR%2FVerticalCardSwiper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJoniVR%2FVerticalCardSwiper/lists"}