Coder Social home page Coder Social logo

snap's Introduction

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.

snap's People

Contributors

hjerpbakk avatar nerdsupremacist avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

snap's Issues

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

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

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?

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!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.