skedgo/TGCardViewController v1.6.1
Card-based view controller for apps that display content cards with accompanying maps, similar to Apple Maps.
βοΈ 7
π 1 year ago
iOS
.package(url: "https://github.com/skedgo/TGCardViewController.git", from: "v1.6.1")
TGCardViewController

Provides a card-based view controller for mapping applications where the card's content is in sync with a map, similar to how Apple Maps works. For an application of this see the TripKitUI SDK and TripGo by SkedGo.
Installation and usage
Install
Via Swift Package Manager (recommended)
- Add it to your
Package.swift
file (or add it as a dependency through Xcode):
.package(url: "https://github.com/skedgo/TGCardViewController.git", from: "1.7.5")
Via CocoaPods
-
Check out the repo and make it accessible to your project, e.g., as a git submodule
-
Add it to your Podfile
, e.g.:
pod 'TGCardViewController
-
Run pod update
Add it to your app
-
Create a TGCardViewController
subclass and use it in your storyboard
-
Override init(coder:)
so that the instance from the storyboard isn't used, but instead TGCardViewController.xib
:
import TGCardViewController
class CardViewController: TGCardViewController {
required init(coder aDecoder: NSCoder) {
// When loading from the storyboard we don't want to use the controller
// as defined in the storyboard but instead use the TGCardViewController.xib
super.init(nibName: "TGCardViewController", bundle: TGCardViewController.bundle)
}
...
}
-
Create a TGCard
subclass, that represents the card at the top level, and add then push that in your view controller's viewDidLoad
:
override func viewDidLoad() {
rootCard = MyRootCard()
super.viewDidLoad()
}
Specs
1. Basic functionality of cards
Behaviour:
- Card positions:
collapsed
: Only shows header of card
peaking
: Shows half of card's content and the map content
extended
: Shows card fully, map shows a little bit on top but is greyed out
- Pushing a card from another card
- β Adds (x) button unless itβs the root card
- β Card has a preferred position which is used when pushing
- β Animation: Slide up from the bottom; fading black view on card below with alpha from 0% to 25%
- β Pass on appearance callbacks appropriately to involved cards
- Popping a card
- β Tap (x) to pop card
- β When popping top card, restore card position of card below when something got pushed on it
- β Animation: Slide back down; fading out black view on card below with alpha from 25% to 0%
- β Pass on appearance callbacks appropriately to involved cards
- Cards are draggable
- β Snap to collapsed (only title), peaking (near half-way showing both map and card content), extended (still shows a bit of the map on top, but darkened)
- β Cards can be dragged up and down anywhere on the card
- β Tap title when collapsed: go to peaking
- β Tap title when peaking: go to extended
- β Tap title when extended: do nothing
- β Tap map when extended: go to peaking
- Cards are scrollable
- β Cards typically have scrolling content: when scrolling down the card's header stays at the top and a bit of the map still keeps peaking through at the top.
- β When scrolling down show a thin separator line between the card's scrolling content and the card's header
- β When scrolling to the top and keeping to scroll, start dragging card
Styles:
- β Animation curve for push and pop
- β Blurry view under status bar (like Maps app)
- β When rotating device and card is collapsed, make sure card ends up in correct position
2. Card content and gestures
Card types:
- Plain card
- β On top: Title, (x), optional subtitle and optional accessory view
- β Add accessory view
- β Content can be scrollable and size adjusts to content. If it fits, it shouldnβt be scrollable
- β Add optional floaty button
- Table card
- β Same as plain card, but with a table view as its content
- β Allow specifying plain (e.g., for departures) or grouped style (e.g., for profile)
- Collection card
- β Same as plain card, but with a collection view as its content
- β Allow specifying collection view layout
- Hosting card
- β Allow using a SwiftUI view as the card's content
- Paging card
- β Handles list of child cards on the same hierarchical level which can be paged programatically and through gestures
- β Has header view: Used for titles (child cards shouldn't show them then) and navigation; Header view is separate from sticky bar, i.e., you can have both.
- β Re-uses the top card's map manager
- β Pass on appearance callbacks appropriately to child cards
Card styles:
- β Rounded corners to cards
- β Grab handle for cards
- β Nice close buttons (and next button for paging cards)
- β Title and subtitle styling
- β Add mini drop shadow to card views
- β Bottom view
3. Map content
Map content:
- β Cards can optionally have map content
- β When showing the content, the insets should be respected to account for the card overlapping the map
- β If thereβs no map content: Show card always extended and don't allow dragging it down (or just snap back up when using tries)
Map buttons:
- β Optional list of buttons that float on the right above the card or in the top right corner (when collapsed or peaking)
- β When dragging up the card to
extended
, the buttons fade away
4. Large width (iPad + iPhone in landscape)
- β Move card to the side with min (iPhone Plus) and max (iPad) width
- β Make sure transitions work when changing size and traits
5. UIKit features
- β State restoration, using
NSUserActivity
- β VoiceOver Accessibility
- β Keyboard shortcuts
End-user documentation
Keyboard shortcuts
- Card controller
- β+β: Expand card
- β+β: Expand/collapse card
- β+w: Pop card or dismiss modal
- Table view cards
- β: Highlight previous item
- β: Highlight next item
- β+β: Highlight item at start of list
- β+β: Highlight item at end of list
- Space or enter: select item
- Esc: deselect
- Paging cards
- β+β: Previous card
- β+β: Next card