Skip to content

Latest commit

 

History

History
187 lines (137 loc) · 7.1 KB

README.md

File metadata and controls

187 lines (137 loc) · 7.1 KB

TGCardViewController

CI

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.

Collapsed

Peaking

Expanded

Custom header


Installation and usage

Install

Via Swift Package Manager (recommended)
  1. 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
  1. Check out the repo and make it accessible to your project, e.g., as a git submodule

  2. Add it to your Podfile, e.g.:

    pod 'TGCardViewController

  3. Run pod update

Add it to your app

  1. Create a TGCardViewController subclass and use it in your storyboard

  2. 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)
      }
    
      ...
    }
  3. 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:
    1. collapsed: Only shows header of card
    2. peaking: Shows half of card's content and the map content
    3. 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