An iOS library for SwiftUI to create draggable sheet experiences similar to iOS applications like Maps and Stocks.

Overview

BottomSheet

An iOS library for SwiftUI to create draggable sheet experiences similar to iOS applications like Maps and Stocks.

Feature overview

The library currently supports;

  • Unlimited snap positions
  • Realtime position callback
  • Absolute and relative positioning
  • Customizable animation parameters
  • An optional sticky header
  • Views with and without a scrollview
  • Custom snap threshold

How to install

Currently BottomSheet is only available through the Swift Package Manager or manual install.

  1. Installation through Swift Package Manager can be done by going to File > Add Packages. Then enter the following URL in the searchbar; github.com/Wouter125/BottomSheet.

  2. Manual installation can be done by cloning this repository and dragging all assets into your Xcode Project.

How to use

  1. Import BottomSheet

  2. Create a custom enum with all snap positions. It can be relative or absolute. Order does not matter. Absolute positioning should look something like this;

enum BottomSheetPosition: CGFloat, CaseIterable {
    case bottom = 182
    case middle = 320
    case top = 700
}

Relative positioning should always be between 0 and 1 and can look like this;

enum BottomSheetRelativePosition: CGFloat, CaseIterable {
    case bottom = 0.216
    case middle = 0.355
    case top = 0.829
}
  1. Create a state property that contains the bottom sheet start position;
@State var position: BottomSheetPosition = .middle
  1. Add the BottomSheetView to your SwiftUI view hierachy;
BottomSheetView(
    position: $position,
    header: { }
    content: { }
}
  1. Optionally tweak the animation curve / snap threshold with a view modifier or receive the current panel position with a callback;
BottomSheetView(
    position: $position,
    header: { }
    content: { }
}
.animationCurve(mass: 1, stiffness: 250)
.snapThreshold(1.8)
.onBottomSheetDrag { translation in
    print("Translation", translation)
}

Interface

Modifier Type Default Description
snapThreshold Double 1.8 The threshold to let the drag gesture ignore the distance. Value between 0 and 3.
animationCurve.mass Double 1.2 The mass of the object attached to the spring.
animationCurve.stiffness Double 200 The stiffness of the spring.
animationCurve.damping Double 25 The spring damping value.

Example

To give you an idea of how to use this library you can use the example that is attached to this repo. Simply clone it and open the BottomSheetExample folder in Xcode.

Roadmap

  1. Add landscape support
  2. Add iPad support
You might also like...
Fully customizable and extensible action sheet controller written in Swift
Fully customizable and extensible action sheet controller written in Swift

XLActionController By XMARTLABS. XLActionController is an extensible library to quickly create any custom action sheet controller. Examples The action

Dice roller, character sheet/ creator, and monster/item info app on the iphone12

DnD-LordDogMaw This file will be the start of a side project in the hopes of creating an iphone12 app for Dungeons and Dragons! This app will have 3 m

Action sheet allows including your custom views and buttons.
Action sheet allows including your custom views and buttons.

CustomizableActionSheet Action sheet allows including your custom views and buttons. Installation CocoaPods Edit your Podfile: pod 'CustomizableAction

Present a sheet ViewController easily and control ViewController height with pangesture
Present a sheet ViewController easily and control ViewController height with pangesture

PanControllerHeight is designed to present a sheet ViewController easily and control ViewController height with pangesture.

This is a small View modifier that adds detents for native .sheet representations that appeared in iOS 16

SheetDetentsModifier This is a small View modifier that adds detents for .sheet representations that appeared in iOS 16 It works starting with iOS 15

Bottom Sheet component is widely used in Joom application

Bottom Sheet Bottom Sheet component is widely used in Joom application Installation Swift Package Manager Swift Package Manager is a tool for managing

BottomSheetDemo - Bottom sheet modal view controller with swift
BottomSheetDemo - Bottom sheet modal view controller with swift

当我们想弹出一个预览视图,bottom sheet modal view controller 非常实用。在 iOS 中,长按拖拽手势可以让 controlle

Share-sheet-example - A sample project that reproduces an issue with Share Sheets

Hello, DTS! This project demonstrates the issue I'm having with the Share Sheet.

SplitSheet - A lightweight, fully interactive split-screen sheet.
SplitSheet - A lightweight, fully interactive split-screen sheet.

SplitSheet A lightweight, fully interactive split-screen sheet. Powered by UIScrollView for super-smooth gestures. Show/hide either programmatically o

Comments
  • Incorrect starting position and weird animation inside NavigationView

    Incorrect starting position and weird animation inside NavigationView

    I am using relative positioning inside a NavigationView. The issue about the wrong position and enter animation makes this library unusable. If there is no NavigationView, there is no issue. But I do need it.

    enum BottomSheetPosition: CGFloat, CaseIterable {
        case top = 0.83
        case middle = 0.385
    }
    
    @State var bottomSheetPosition: BottomSheetPosition = .middle
    
    BottomSheetView(
                    position: $bottomSheetPosition,
                    header: {
                    },
                    content: {
                        ForecastView(bottomSheetTranslationProrated: bottomSheetTranslationProrated)
                        
                    }
                )
                .onBottomSheetDrag { translation in
                    bottomSheetTranslation = translation
    
                    withAnimation(.easeInOut) {
                        if bottomSheetPosition == BottomSheetPosition.top {
                            hasDragged = true
                        } else {
                            hasDragged = false
                        }
                    }
                }
    

    https://user-images.githubusercontent.com/33760969/170066308-c2393fbb-04ed-47d0-a618-1f2695e4746f.mov

    bug 
    opened by Dara-To 8
  • Scroll view moves to the top after position changing

    Scroll view moves to the top after position changing

    Hey. Thanx for such awesome lib)

    To reproduce: In sample app drag sheet to top position, the drag content even higher. Then drag header to any other position without touching content. After that try to drag content.

    opened by ValeriyJefimov 3
  • To do for stable release

    To do for stable release

    • [x] Safely unwrap the actual position after dragging. Can be nil which causes a hard crash
    • [x] When state changes make the UI reflect those changes by using updateUIViewController
    • [x] Move modulate function into the ondrag modifier so value is always between 0 and 1 instead of the raw numbers.
    • [ ] Find vertical scrollview based on tag to prevent crashes on multiple nested scrollviews.
    • [x] Include manual disable and enable drag functionality.
    • [x] Add the ability to exclude values from the snapping enum
    • [x] Improve position callbacks to better handle certain scroll cases.
    opened by Wouter125 1
  • Feat/bottom sheet plus

    Feat/bottom sheet plus

    Working on a new interface for bottom sheet. Will be renamed to bottom sheet plus, and follow a similar pattern to what Apple implemented in iOS 16, but with iOS 14+ support.

    Will allow for:

    • [x] Combining fixed heights, fractions and predefined heights
    • [x] Interchangeable with the iOS 16 API
    • [x] Having a height callback on your sheet presentation for custom interactions
    • [x] Support for a sticky header
    struct RefactorExample: View {
        @State var selectedDetent: BottomSheet.PresentationDetent = .large
        @State var isPresented: Bool = false
        
        var body: some View {
            VStack {
                Button("Test", action: {
                    isPresented.toggle()
                })
                Text("\(selectedDetent.size)")
                Spacer()
            }
                .sheetPlus(
                    isPresented: $isPresented,
                    onDismiss: {
                      print("Dismissing")
                    },
                    header: {
                        HStack {
                            Text("Header")
                            Spacer()
                        }
                        .frame(height: 48)
                        .background(Color.orange)
                    },
                    main: {
                        VStack(spacing: 0) {
                            ForEach(0..<100, id: \.self) { obj in
                                HStack {
                                    Spacer()
                                    Text("\(obj)")
                                    Spacer()
                                }
                            }
                        }
                        .presentationDetentsPlus(
                            [.medium, .large],
                            selection: $selectedDetent
                        )
                    }
                )
        }
    }
    
    enhancement 
    opened by Wouter125 0
Releases(1.4.5)
  • 1.4.5(Jun 3, 2022)

    What's Changed

    • Fix/animate bugfix by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/13

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.4.4...1.4.5

    Source code(tar.gz)
    Source code(zip)
  • 1.4.4(May 24, 2022)

    What's Changed

    • Fix/scrollview bugfixes by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/12

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.4.3...1.4.4

    Source code(tar.gz)
    Source code(zip)
  • 1.4.3(Apr 24, 2022)

    What's Changed

    • Feat/scroll bug by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/10

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.4.2...1.4.3

    Source code(tar.gz)
    Source code(zip)
  • 1.4.2(Apr 23, 2022)

    What's Changed

    • Feat/scroll bug by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/9

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.4.1...1.4.2

    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Apr 19, 2022)

    What's Changed

    • Feat/scroll bug by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/8

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.4.0...1.4.1

    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Apr 19, 2022)

    What's Changed

    • Feat/small bugfixes by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/7

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.3.0...1.4.0

    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Apr 4, 2022)

    What's Changed

    • fix: implement missing updateUIViewController and safely unwrap position by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/5

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.2.2...1.3.0

    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Mar 24, 2022)

    What's Changed

    • Fix/background color by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/3

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.2.0...1.2.1

    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Mar 24, 2022)

    What's Changed

    • Feat/snapthreshold by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/2

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.1.0...1.2.0

    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Mar 20, 2022)

    What's Changed

    • Feat/relative positioning by @Wouter125 in https://github.com/Wouter125/BottomSheet/pull/1

    Full Changelog: https://github.com/Wouter125/BottomSheet/compare/1.0.2...1.1.0

    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Mar 10, 2022)

  • 1.0.1(Mar 10, 2022)

  • 1.0.0(Mar 10, 2022)

Owner
Wouter
Swift and React explorer with a passion for design.
Wouter
A customizable framework to create draggable views

CFNotify CFNotify is written in Swift. Using UIKit Dynamics as animator. It can make ANY UIView object draggable and throwable. This library mainly us

Johnny Tsoi 491 Nov 20, 2022
A customizable framework to create draggable views

CFNotify CFNotify is written in Swift. Using UIKit Dynamics as animator. It can make ANY UIView object draggable and throwable. This library mainly us

Johnny Tsoi 491 Nov 20, 2022
Custom-action-sheet- - Custom action sheet with swift

Custom-action-sheet- Usage let alertController: UIAlertControllerDimmed = UIAler

Girisankar G 0 Jan 19, 2022
A Google like action sheet for iOS written in Swift.

MaterialActionSheetController Lightweight and totally customizable. Create and present it the way you do with UIAlertController. Screenshots Demo | De

Thanh-Nhon NGUYEN 103 Jun 29, 2022
Customizable Dynamic Bottom Sheet Library for iOS

DynamicBottomSheet Powerd by Witi Corp., Seoul, South Korea. Fully Customizable Dynamic Bottom Sheet Library for iOS. This library doesn't support sto

Witi Official 10 May 7, 2022
A Swift library to provide a bouncy action sheet

Hokusai is a Swift library that provides a bouncy action sheet. It will give the users a fancy experience without taking pains coding the cool animati

Yuta Akizuki 430 Nov 20, 2022
DGBottomSheet - The lightest swift bottom sheet library

DGBottomSheet Requirements Installation Usage DGBottomSheet The lightest swift b

donggyu 9 Aug 6, 2022
Multiplatform (iOS, macOS) SwiftUI bottom sheet drawer. Expandable bottomsheet. Slide out bottom menu

Multiplatform (iOS, macOS) SwiftUI bottom sheet drawer Features It does not re-render the background content while manipulating with the sheet iOS and

Igor 8 Nov 18, 2022
Create Apple-like alerts & toasts using SwiftUI

AlertToast-SwiftUI Present Apple-like alert & toast in SwiftUI ?? Example ?? Overview Currently in SwiftUI, the only way to inform the user about some

Elai Zuberman 1.1k Dec 29, 2022
A SwiftUI Partial Sheet fully customizable with dynamic height

A SwiftUI Partial Sheet fully customizable with dynamic height

Andrea Miotto 1.4k Jan 5, 2023