Skip to content

A customizable Snapping Drawer à la Apple Maps.

 100% in SwiftUI.

License

Notifications You must be signed in to change notification settings

nerdsupremacist/Snap

Repository files navigation

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.