A SwiftUI card view, made great for setup interactions.

Overview

SlideOverCard Project logo

Twitter: @joogps

A SwiftUI card design, similar to the one used by Apple in HomeKit, AirPods, Apple Card and AirTag setup, NFC scanning, Wi-Fi password sharing and more. It is specially great for setup interactions.

Clear Spaces demo QR code scanner demo Example preview demo

From left to right: SlideOverCard being used in Clear Spaces, a QR code scanner prompt (made with CodeScanner) and a demo of the project's Xcode preview

Installation

This repository is a Swift package, so all you gotta do is search and include it in your project under File > Swift Package Manager. Then, just add import SlideOverCard to the files where this package will be referenced and you're good to go!

If your app runs on iOS 13, you might find a problem with keyboard responsiveness in your layout. That's caused by a SwiftUI limitation, unfortunately, since the ignoresSafeArea modifier was only introduced for the SwiftUI framework in the iOS 14 update.

Usage

You can add a card to your app in two different ways. The first one is by adding a .slideOverCard() modifier, which works similarly to a .sheet():

.slideOverCard(isPresented: $isPresented) {
  // Here goes your awesome content
}

Here, $isPresented is a boolean binding. This way you can dismiss the view anytime by setting it to false. This view will have a transition, drag controls and an exit button set by default. You can override this by setting the dragEnabled, dragToDismiss and displayExitButton boolean parameters:

// This creates a card that can be dragged, but not dismissed by dragging
.slideOverCard(isPresented: $isPresented, options: [.disableDragToDismiss]) {
}

// This creates a card that can't be dragged or dismissed by dragging
.slideOverCard(isPresented: $isPresented, options: [.disableDrag, .disableDragToDismiss]) {
}

// This creates a card with no exit button
.slideOverCard(isPresented: $isPresented, options: [.hideExitButton]) {
}

In case you want to execute code when the view is dismissed (either by the exit button or drag controls), you can also set an optional onDismiss closure parameter:

// This card will print some text when dismissed
.slideOverCard(isPresented: $isPresented, onDismiss: {
    print("I was dismissed.")
}) {
    // Here goes your amazing layout
}

Alternatively, you can add the card using a binding to an optional enumeration. That will automatically animate the card between screen changes.

// This uses a binding to an optional object in a switch statement
.slideOverCard(item: $activeCard) { item in
    switch item {
        case .welcomeView:
            WelcomeView()
        case .loginView:
            LoginView()
        default:
            ..........
    }
}

You can even instantiate a card by your own by adding a SlideOverCard view to a ZStack.

// Using the standalone view
ZStack {
    Color.white
    
    SlideOverCard(isPresented: $isPresented) {
        // Here goes your super-duper cool screen
    }
}

Accessory views

This package also includes a few accessory views to enhance your card layout. The first one is the SOCActionButton() button style, which can be applied to any button to give it a default "primary action" look, based on the app's accent color. The SOCAlternativeButton() style will reproduce the same design, but with gray. And SOCEmptyButton() will create an all-text "last option" kind of button. You can use them like this:

Button("Do something", action: {
  ...
}).buttonStyle(SOCActionButton())

There's also the SOCExitButton() view. This view will create the default exit button icon used for the card (based on https://github.com/joogps/ExitButton).

Manager

If you want to show a card as an overlay to all content in the screen, including the tab and navigation bars, you should use the SOCManager. The manager helps you display a card as a transparent view controller that covers the screen, therefore going past your SwiftUI content. To present this overlay, use:

SOCManager.present(isPresented: $isPresented) {
    // Here goes your design masterpiece
}

And to dismiss, just call:

SOCManager.dismiss(isPresented: $isPresented)

Example

The SwiftUI code for a demo view can be found here. It's an Xcode preview, and you can experience it right within the package, under Swift Package Dependencies, in your project.

Comments
  • Card hidden behind tab bar.

    Card hidden behind tab bar.

    When using a tab bar, and showing a SlideOverCard on a subview, the card is hidden behind the tab bar. Is there any way that the y offset could take into account the height of the tab bar?

    Code to reproduce:

    import SwiftUI
    import SlideOverCard
    
    struct ContentView: View {
        @State var tab: Int = 0
        
        
        var body: some View {
            TabView(selection: $tab) {
                View1()
                    .tabItem { Image(systemName: "rectangle") }
                    .tag(0)
                View2()
                    .tag(1)
                    .tabItem { Image(systemName: "rectangle") }
            }
        }
    }
    
    struct View1: View {
        var body: some View {
            Text("View 1")
        }
    }
    struct View2: View {
        @State var showCard: Bool = false
        
        var body: some View {
            ZStack {
                VStack {
                    Text("View 2")
                        .font(.largeTitle)
                    Button(action: { self.showCard = true }) {
                        Text("Show card!")
                    }
                    ScrollView() {
                        ForEach(0..<100) { i in
                            Text("\(i)")
                                .font(.caption)
                        }
                    }
                }
            }
            .slideOverCard(isPresented: $showCard) {
                VStack {
                    Image(systemName: "clock")
                        .font(.largeTitle)
                    Text("Card is showing, but is cut off ...")
                        .font(.subheadline)
                }
            }
    
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    enhancement 
    opened by Andreasgejlm 5
  • Documentation need to be updated for Xcode 13?

    Documentation need to be updated for Xcode 13?

    This might be actually my limited knowledge on how to use Swift Packages but the documentation says that I'm supposed to go to File > Swift Package Manager.

    I don't see such menu item so I was trying to do it another way but still can't make it work:

    2022-01-06 17 34 06

    Any hints on how to link this package?

    opened by adams-family 3
  • Add support for multiple items

    Add support for multiple items

    Add support so that the view can be called with multiple items such as

            .sheet(item: $activeSheet) { item in
                switch item {
                case .photoPicker:
                    ImagePicker(selectedImage: $imageBuffer, sourceType: .photoLibrary)
                case ........
    
    enhancement 
    opened by chih98 3
  • Error with `.slideOverCard`

    Error with `.slideOverCard`

    iOS 15.2

    Xcode Version 13.2.1 (13C100)

    My ContentView.swift:

    import SwiftUI
    
    struct ContentView: View {
        
        @State private var showCard = false
        var body: some View {
            HStack{
                Text("Hello, world!")
                    .padding()
                Button("abb"){
                    showCard = true
                }
            }
            .slideOverCard(isPresented: $showCard ) {
                Text("Hello, world!")
                  // Here goes your awesome content
                }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

    And the error:

    🔴 Value of type 'HStack<TupleView<(some View, Button<Text>)>>' has no member 'slideOverCard'
    
    • If I use .sheet, no error occurs. Why?
    import SwiftUI
    
    struct ContentView: View {
        
        @State private var showCard = false
        var body: some View {
            HStack{
                Text("Hello, world!")
                    .padding()
                Button("abb"){
                    showCard = true
                }
            }
            .sheet(isPresented: $showCard ) {
                Text("Hello, world!")
                  // Here goes your awesome content
                }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    
    opened by sunshinewithmoonlight 2
  • Change slide over position and possible options

    Change slide over position and possible options

    Hi @joogps,

    I wanted to know how to make the slide to open from different position instead from the default bottom position.

    Sorry if I have missed it from the SOCManager, I didn't get it very well.

    Regards,

    opened by chellem 2
  • Issue with Xcode 13 beta 3

    Issue with Xcode 13 beta 3

    
    UIApplication.shared.windows.first?.rootViewController?.present(controller, animated: false)
            DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
    
    

    'shared' is unavailable in application extensions for iOS: Use view controller based solutions where appropriate instead.

    opened by Aurther-Nadeem 2
  • Fix for XCode 13 beta 3

    Fix for XCode 13 beta 3

    XCode beta 3 needs some small additions in order to compile the code correctly (have a look here: https://twitter.com/twannl/status/1415643870512226307)

    bug 
    opened by Wouter01 2
  • Removing redundant .swiftpm folder

    Removing redundant .swiftpm folder

    The .swiftpm folder contains some xcode files that if you add the library to a project, it will add a new target scheme. This commit will prevent that situation Screen Shot 2022-05-14 at 11 35 40 AM

    opened by Rminsh 1
  • iOS 13 Support?

    iOS 13 Support?

    Hi, thanks for this great work! I think the iOS 14 requirement is unnecessary for this, you can easily integrate this for iOS 13 too. This is just a suggestion and it's important I think :)

    Anyway, thanks again :)

    enhancement 
    opened by halilyuce 1
  • Bible

    Bible

    // This creates a card that can be dragged, but not dismissed by dragging .slideOverCard(isPresented: $isPresented, options: [.disableDragToDismiss]) { }

    // This creates a card that can't be dragged or dismissed by dragging .slideOverCard(isPresented: $isPresented, options: [.disableDrag, .disableDragToDismiss]) { }

    // This creates a card with no exit button .slideOverCard(isPresented: $isPresented, options: [.hideExitButton]) { }

    opened by dj77566 0
  • SOCManager present animation speed

    SOCManager present animation speed

    Version: SlideOverCard 2.0.0, Xcode 13.3 Issue: Unnaturally fast animation when displaying a card using SOCManager.present vs .slideOverCard(isPresented.

    I would expect both versions to display the card at the same animation speed. The SOCManager presents the card so quickly that it feels off.

    Potential Quick Fix: Give the SOCManager the same animation speed as the slideOverCard

    Potential Enhancement: Add and option to change the speeds between slow, medium, fast, and or passing in custom animation speeds

    Code snippets:

    Button {
        showLogIn = true
    
        SOCManager.present(isPresented: $showLogIn, onDismiss: {
           // code
        }, options: [.disableDrag, .disableDragToDismiss, .hideExitButton]) {
          SomeView(isPresented: $showLogIn)
        }
      }
    }
    
    .slideOverCard(isPresented: $showView, options: [.disableDrag, .disableDragToDismiss, .hideExitButton]) {
      SomeView(isPresented: $showSummary)
    }
    

    Thank you for your time.

    opened by wambambizzle 1
  • How to manually add to a project?

    How to manually add to a project?

    Hi,

    I would like to use this in Swift Playgrounds? I was thinking that the best way to do this was copy and paste the source files, but I'm not sure which ones to copy and to where?

    Thanks

    opened by Aiyush-G 0
Releases(2.1.0)
Owner
João Gabriel
student, coder, cool human wannabe. ifsc ‘23; @apple WWDC ‘20, ‘21 Scholar. 15 he/him
João Gabriel
IOS Card Game - A simple card game using SwiftUI

IOS_Card_Game A simple card game using Swift UI.

Md. Masum Musfique 1 Mar 25, 2022
SimpleCardView-SwiftUI is a very simple card view written with SwiftUI

SimpleCardView-SwiftUI is a very simple card view written with SwiftUI

Tomortec 3 May 19, 2022
Card-based view controller for apps that display content cards with accompanying maps, similar to Apple Maps.

TripGo Card View Controller This is a repo for providing the card-based design for TripGo as well as the TripKitUI SDK by SkedGo. Specs 1. Basic funct

SkedGo 6 Oct 15, 2022
A SwiftUI based custom sheet card to show information in iOS application.

A SwiftUI based custom sheet card to show any custom view inside the card in iOS application.

Mahmud Ahsan 4 Mar 28, 2022
A reactive, card-based UI framework built on UIKit for iOS developers.

CardParts - made with ❤️ by Intuit: Example Requirements Installation Communication & Contribution Overview Quick Start Architecture CardsViewControll

Intuit 2.5k Jan 4, 2023
This UI attempts to capture the Quibi Card Stack and the associated User Interaction.

RGStack This UI attempts to capture the Quibi Card Stack and the associated User Interaction. Required A View that conforms to the ConfigurableCard pr

RGeleta 96 Dec 18, 2022
Card flip animation by pan gesture.

CardAnimation Design from Dribble. 实现思路在这里。 Two Solutions At the begin, I didn't encapsulate code, @luxorules refactor code into class and improve it

null 1.2k Dec 14, 2022
Awesome looking Dial like card selection ViewController

KVCardSelectionVC Awesome looking Dial like card selection ViewController An updated Swift 3 working version of : https://github.com/atljeremy/JFCardS

Kunal Verma 23 Feb 1, 2021
🃏 Tinder like card interface

Features Swift 3 Custom views for the card & overlay Generic Dynamically add new cards on top or on the bottom Lazy view loading Setup pod 'DMSwipeCar

Dylan Marriott 250 Nov 15, 2022
Cusom CollectionView card layout

MMCardView Example To run the example project, clone the repo, and run pod install from the Example directory first. Demo 1.Card Requirements iOS 8.0+

Millman Yang 556 Dec 5, 2022
:star: Custom card-designed CollectionView layout

CardsLayout CardsLayout is a lightweight Collection Layout. Installation CocoaPods You can use CocoaPods to install CardsLayout by adding it to your P

Filipp Fediakov 798 Dec 28, 2022
🔥 A multi-directional card swiping library inspired by Tinder

Made with ❤️ by Mac Gallagher Features ?? Advanced swipe recognition based on velocity and card position ?? Manual and programmatic actions ?? Smooth

Mac Gallagher 754 Dec 28, 2022
An iOS library to create beautiful card transitions.

CSCardTransition CSCardTransition is a small library allowing you to create wonderful push and pop transition animations like in the App Store. It wor

Creastel 5 Jan 14, 2022
GLScratchCard - Scratch card effect

I loved the way payments app's like Google pay and PhonePe used scratch card option to reward it's user. Hence with ?? cloned the same scratch card effect for you guys out there

Gokul 84 Dec 5, 2022
A easy-to-use SwiftUI view for Tinder like cards on iOS, macOS & watchOS.

?? CardStack A easy-to-use SwiftUI view for Tinder like cards on iOS, macOS & watchOS. Installation Xcode 11 & Swift Package Manager Use the package r

Deniz Adalar 285 Jan 3, 2023
A SwiftUI view that arranges its children in a whimsical interactive deck of cards, as seen in Big News

CardStack A SwiftUI view that arranges its children in a whimsical interactive deck of cards. CardStack mimics the behaviour of the photo stack in iMe

The Not So Big Company 74 Dec 13, 2022
A navigation controller that displays its view controllers as an interactive stack of cards.

CardNavigation The easiest way to turn a navigation controller into an interactive stack of cards. Highlights ✅ Fully interactive and interruptible ✅

James Randolph 41 Sep 29, 2022
Swipe to "like" or "dislike" any view, just like Tinder.app. Build a flashcard app, a photo viewer, and more, in minutes, not hours!

MDCSwipeToChoose Swipe to "like" or "dislike" any view, just like Tinder.app. Build a flashcard app, a photo viewer, and more, in minutes, not hours!

Brian Gesiak 2.6k Nov 29, 2022
Recreation of cards from Apple's AppStore written using SwiftUI.

App Store Cards Animation I tried to reproduce the look and the feeling of the cards from the AppStore. Please note that this repository is a work-in-

Roman 3 Mar 30, 2022