A customizable Snapping Drawer à la Apple Maps.

 100% in SwiftUI.

Overview

Snap

A customizable Snapping Drawer à la Apple Maps, Apple Music, Stocks, Overcast, etc.. 100% in SwiftUI

This is heavily inspired by Rideau and based on this Gist by mshafer.

Here's a short demo where I reconstructed the Apple Maps UI:

Installation

Swift Package Manager

You can install Snap via Swift Package Manager by adding the following line to your Package.swift:

import PackageDescription

let package = Package(
    [...]
    dependencies: [
        .package(url: "https://github.com/nerdsupremacist/Snap.git", from: "0.1.0")
    ]
)

Usage

Snap allows you to set up either 1, 2 or 3 Snapping points and customize your UI depending on where you are.

For example if we want to recreate the Apple Maps UI we could write the following:

import MapKit
import Snap
import SwiftUI

struct ContentView: View {
    @State private var region = MKCoordinateRegion(...)

    var body: some View {
        ZStack {
            Map(coordinateRegion: $region)

            SnapDrawer(large: .paddingToTop(24), medium: .fraction(0.4), tiny: .height(100), allowInvisible: false) { state in
                VStack(alignment: .leading, spacing: 10) {
                    SearchBar()

                    if state != .tiny {
                        Favorites()
                            .transition(.scale)
                    }

                    if state == .large {
                        Recents()
                            .transition(.scale)
                    }
                }
            }
        }
    }
}

Feel free to explore the API yourself and play around with it.

Other features include:

  • Listening to state changes via a @Binding
  • Setting a background view

Contributions

Contributions are welcome and encouraged!

License

Snap is available under the MIT license. See the LICENSE file for more info.

Comments
  • Drawer breaks navigation title layout

    Drawer breaks navigation title layout

    Hey, thanks for making such a nice-looking component! I'm excited to start using it, but it's breaking the layout of my navigation bar titles. Here's a simple view without Snap:

    struct MyContentView: View {
        @State var drawerState: AppleMapsSnapState = .tiny
    
        var body: some View {
            NavigationView {
                ZStack {
                    List {
                        ForEach(1 ..< 100, id: \.self) { n in
                            Text("\(n)")
                        }
                    }
                }
                .navigationBarTitle("Numbers")
            }
        }
    }
    

    Screen Shot 2020-07-30 at 1 55 09 PM

    Adding a Snap drawer into the ZStack breaks the nav title - it's now overlapping the list items (as though it were above them in a ZStack).

    struct MyContentView: View {
        @State var drawerState: AppleMapsSnapState = .tiny
    
        var body: some View {
            NavigationView {
                ZStack {
                    List {
                        ForEach(1 ..< 100, id: \.self) { n in
                            Text("\(n)")
                        }
                    }
                    SnapDrawer(
                        state: $drawerState,
                        large: .paddingToTop(24),
                        medium: .fraction(0.6),
                        tiny: .height(80),
                        allowInvisible: false
                    ) { _ in
                        Text("Snap")
                    }
                }
                .navigationBarTitle("Numbers")
            }
        }
    }
    

    Screen Shot 2020-07-30 at 1 55 30 PM

    Do you have any ideas on how to fix this?

    opened by akshayjshah 1
  • Ensure that the SnapDrawer respects the initial state set by the parent View

    Ensure that the SnapDrawer respects the initial state set by the parent View

    Currently, I have the drawer in a .tinyState or invisible by default. I do so from my parent's initial @State. However, SnapDrawer starts out in its large form, even when a binding with its own initial value has already been set. This change ensures the initial value defined is derived from the binding unless no binding is provided.

    opened by Joannis 0
  • Customization

    Customization

    This is a great library; it's pretty smooth. Thanks for making & sharing this 🙏


    I'd like to change a few things about the default drawer:

    1. corner radius – a bit too much for my taste
    2. shadow – too big & dark imho
    3. starting position – can it be at the smallest position when being first shown?
    4. bottom margin – for some reason, I see a very big bottom margin below my content. can that be removed? I'm showing a list there which should go all the way to the bottom

    These things should either not be added by default so I can add them later manually, or I would need a way to override them / pass values for them. As for implementation, maybe sth. similar to ButtonStyle would be suitable.

    This would be great! Thanks!

    opened by LinusGeffarth 0
  • Invisible/visible state animation

    Invisible/visible state animation

    When the state is set to .invisible, instead of sliding down to height 0 and disappear, it fades and shrinks to the center (I assume the only view left is the Handle, then disappears. The same applies when setting the visible state back

    opened by nakp 1
  • Scrolling behaviour when using List inside the Drawer

    Scrolling behaviour when using List inside the Drawer

    The dragging gesture will not be recognised to close/open the drawer.

    The behaviour of Apple Maps app is to close the drawer when the table view is at the top when scrolling down.

    opened by antranapp 0
  • Support Percent Driven transitions

    Support Percent Driven transitions

    Currently the transition between states happens after the user has released their finger.

    It would be cool if the transition was interactive as the user dragged their finger. I'm not entirely sure how this could be done, but it's worth a try

    enhancement help wanted 
    opened by nerdsupremacist 0
Releases(0.2.2)
Owner
Mathias Quintero
Developer, Student, Spaghetti Code Enthusiast and Professional Swear Word Sayer.
Mathias Quintero
Apple Maps combined with the OpenWeather API written in SwiftUI

TempAtlas in SwiftUI TemperatureAtlas uses Apple Maps combined with the OpenWeather API written in SwiftUI. This project was built to explore SwiftUI

Justin Hatin 13 Apr 19, 2022
🎲 100% SwiftUI 2.0, classic 2048 game [SwiftUI 2.0, iOS 14.0+, iPadOS 14.0+, macOS 11.0+, Swift 5.3].

swiftui-2048 If you like the project, please give it a star ⭐ It will show the creator your appreciation and help others to discover the repo. ✍️ Abou

Astemir Eleev 174 Dec 17, 2022
This SwiftUI project is a result of the third 'milestone' in "Hacking With Swift's 100 Days of SwiftUI".

exercise-tracker This SwiftUI project is a result of the third 'milestone' in "Hacking With Swift's 100 Days of SwiftUI". In this exercise tracking ap

Eric Tolson 2 Dec 14, 2022
All the projects from 100 Days of SwiftUI, as taught by Paul Hudson (Hacking with Swift)

100 Days of SwiftUI 19 projects of increasing complexity built with SwiftUI. These projects were built as part of an iOS development course taught by

Emmanuel Chucks 7 Dec 4, 2022
100-Days-of-SwiftUI - a free online course created and delivered by Paul Hudson

100-Days-of-SwiftUI DESCRIPTION 100 Days of SwiftUI is a free online course crea

null 0 Jan 9, 2022
A completely native Discord client for macOS built 100% in Swift and SwiftUI

Swiftcord A completely native Discord client for macOS built 100% in Swift and SwiftUI This project aims to create a fully functional native Discord c

CryptoAlgo-Dev 1.1k Jan 9, 2023
Reusable & customizable SwiftUI settings sheet as a Swift package

PackAPrefPane Reusable & customizable SwiftUI settings sheet as a Swift package Features Swift package 100% Swift 99% SwiftUI Simple design Lightweigh

W1W1-M 9 Nov 6, 2022
A native, customizable SwiftUI refresh control

Refresher A customizable, native Swift UI refresh control for iOS 14+ Why? the native SwiftUI refresh control only works on iOS 15+ the native UIKit r

Brian Floersch 26 Nov 29, 2022
Completed Project for Authentication in SwiftUI using Firebase Auth SDK & Sign in with Apple

Completed Project for Authentication in SwiftUI using Firebase Auth SDK & Sign in with Apple Follow the tutorial at alfianlosari.com Features Uses Fir

Alfian Losari 43 Dec 22, 2022
Social Media platform build with swiftUI and Firebase with google and apple account integration for Signing In Users

Social Media platform build with swiftUI and Firebase with google and apple account integration for Signing In Users . Providing Users availability to upload posts and images add caption allowing other users to comment , with Find section to explore new people , new stories , User Profile section to allow the user to take control of his account .

Devang Papinwar 2 Jul 11, 2022
Apple products application using SwiftUI

SwiftUI-Prototype In this project I built 2 interfaces for "Apple products" appl

Najla Alshehri 0 Jul 9, 2022
Apple Watch-style activity ring for SwiftUI.

WolfActivityRing Apple Watch-style activity ring for SwiftUI. Originally inspired by Eric Callanan's Create Activity Rings in SwiftUI with a number of

Wolf McNally 6 Sep 16, 2022
A SwiftUI component which handles logging in with Apple to Firebase

Login with Apple Firebase SwiftUI I made this SwiftUI component to handle logging in with Apple to Firebase. Demo Gif Usage in SwiftUI struct ContentV

Joe Hinkle 153 Dec 23, 2022
This To-Do app was developed using Swift and SwiftUI and works on iOS, MacOS (Apple Silicon) and WatchOS. The tasks are kept on storage even when the app is restarted.

ToDo-SwiftUI This app has a lot of sentimental value for me, given that it helped me a lot to understand the process of doing an iOS app and became th

Augusto Galindo Ali 6 Jul 12, 2022
SwiftUI sample code for Apple's WWDC18 talk "Designing Fluid Interfaces".

Fluid Interfaces SwiftUI SwiftUI sample code for Apple's WWDC18 talk "Designing Fluid Interfaces". What is Fluid Interfaces? Fluid Interfaces is a new

 Frad LEE 32 Oct 7, 2022
iAppStroe is an Apple Store tool app written in SwiftUI.

iAppStore 简介 iAppStroe 是一款使用 SwiftUI 打造的苹果商店工具类 App。 1、提供苹果实时榜单查询,包含 iOS 和 iPad 的热门免费榜、热门付费榜、畅销榜,还有新上架榜、新上架免费榜、新上架付费榜等。 2、提供查询 app 详细页面内容、搜索 app、订阅 ap

37iOSTeam 272 Dec 30, 2022
A simple Apple Watch app to remind you to drink water!

Waterminder A simple Apple Watch app to remind you to drink water. Built with SwiftUI and Combine You can find an article explaining the implementatio

Carlos Corrêa da Silva 184 Dec 31, 2022
Weathy is an Open Source Song/Musician search for Apple Music

Weathy is an Open Source Apple Music Search App You can search for Musician or Songs to play it on Apple Music / Itunes You can find the main Source i

Marvin Hülsmann 4 Jul 12, 2021
EU Digital COVID Certificate Kit for the Apple Platform  (unofficial)

EU Digital COVID Certificate Kit A Swift Package to decode, verify and validate EU Digital COVID Certificates for iOS, tvOS, watchOS and macOS Disclai

Sven Tiigi 32 Oct 4, 2022