Swiftpack.co - GlennBrann/ManySheets as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
GlennBrann/ManySheets
Custom SwiftUI Bottom Sheet Components
.package(url: "https://github.com/GlennBrann/ManySheets.git", from: "1.1.0")

ManySheets

A list of SwiftUI Bottom Sheet components

SwiftPM compatible Swift Version License

ManySheets has a list of custom SwiftUI Bottom Sheet components.

  1. DefaultBottomSheet: A dynamic bottom sheet that scales based on content height inside.
  2. ScaffoldBottomSheet: A scaffolding bottom sheet with three positions (top, middle, bottom).
  3. BottomSheetPresenter: A bottom sheet using UISheetPresentationController in iOS 15

See below for examples and customization.

Installation

Requirements

  • iOS 15.0+
  • Xcode 13+
  • Swift 5+

Swift Package Manager

In Xcode, select: File > Swift Packages > Add Package Dependency.

Paste the package github url in the search bar https://github.com/GlennBrann/ManySheets and press next and follow instructions given via Xcode to complete installation.

You can then add ManySheets to your file by adding import ManySheets.

Or

Add this project on your Package.swift

import PackageDescription

let package = Package(
    dependencies: [
        .Package(url: "https://https://github.com/GlennBrann/ManySheets.git", from: "1.0.5")
    ]
)

DefaultBottomSheet

The DefaultBottomSheet is a basic bottom sheet that scales automatically depending on the content size within. You can add it directly into your view like so

DefaultBottomSheet(isOpen: style: options: content:)

or via the modifier

View().defaultBottomSheet(isOpen: style: options: content:)

Parameters:

  • isOpen - A binding used to display the bottom sheet.
  • style - A property containing all bottom sheet styling DefaultBottomSheetStyle
  • options - An array that contains the bottom sheet options DefaultBottomSheetOptions.Options
  • content - A ViewBuilder used to set the content of the bottom sheet.

DefaultBottomSheet - Example

Simulator Screen Recording - iPhone 12 mini - 2021-09-19 at 17 08 30

import SwiftUI
import ManySheets

struct DefaultBottomSheetExample: View {
    
    @State var showSheet: Bool = false
    
    let bottomSheetStyle = BottomSheetStyle(backgroundColor: .white)
    
    var body: some View {
        ZStack {
            VStack {
                Button(action: { showSheet.toggle() },
                       label: { Text("Show Default Sheet") })
            }
            DefaultBottomSheet(
                isOpen: $showSheet,
                style: bottomSheetStyle,
                options: [.enableHandleBar, .tapAwayToDismiss, .swipeToDismiss]
            ) {
                VStack(alignment: .leading) {
                    HStack(alignment: .top) {
                        Image(systemName: "info.circle")
                        Text("Photos attached must be of cats and cats only")
                            .fixedSize(horizontal: false, vertical: true)
                    }
                    .padding(.bottom, 4)
                    Button(
                        action: { },
                        label: {
                            HStack {
                                Image(systemName: "camera")
                                    .foregroundColor(Color.blue)
                                Text("Take a photo")
                            }
                        }
                    )
                    .frame(height: 44)
                    Button(
                        action: { },
                        label: {
                            HStack {
                                Image(systemName: "photo.on.rectangle")
                                    .foregroundColor(Color.blue)
                                Text("Choose a photo")
                            }
                        }
                    )
                    .frame(height: 44)
                }
                .padding()
                .padding(.bottom, 16)
                .buttonStyle(PlainButtonStyle())
            }
        }
    }
}

ScaffoldBottomSheet

The ScaffoldBottomSheet is a bottom sheet that has three positions top, middle, and bottom. This bottom sheet can scroll content when fully open. This can be disabled by adding the .disableScroll option.

ScaffoldBottomSheet(isOpen: style: options: positions: defaultPosition: headerContent: bodyContent:)

or via the modifier

View().scaffoldBottomSheet(isOpen: style: options: positions: defaultPosition: headerContent: bodyContent:)

Parameters:

  • isOpen - A binding used to display the scaffold bottom sheet.
  • style - A property containing all scaffold bottom sheet styling ScaffoldBottomSheetStyle
  • options - An array that contains the bottom sheet options ScaffoldBottomSheet.Options
  • positions - A ScaffoldBottomSheetPositionsstruct containing the top, middle, and bottom height percentages. Note: these values must be decimal representations of percentages i.e ((middle: 0.5) = 50% height)
  • defaultPosition - The default position the scaffold bottom sheet will be in when isOpen from a closed state.
  • headerContent - An optional header content view builder
  • bodyContent - A ViewBuilder used to set the body content of the scaffold bottom sheet.

ScaffoldBottomSheet - Example

Simulator Screen Recording - iPhone 12 mini - 2021-09-19 at 18 07 20

import SwiftUI
import ManySheets

struct ContentView: View {
    
    @State var showSheet: Bool = false
    
    let bottomSheetStyle = ScaffoldBottomSheetStyle(backgroundColor: .white)
    let positions = ScaffoldBottomSheetPositions(top: 1, middle: 0.5, bottom: 0.13)
    
    var body: some View {
        ZStack {
            VStack {
                Button(action: { showSheet.toggle() },
                       label: { Text("Show Scaffold Sheet") })
            }
            ScaffoldBottomSheet(
                isOpen: $showSheet,
                style: bottomSheetStyle,
                options: [.enableHandleBar, .tapAwayToDismiss, .swipeToDismiss],
                positions: positions,
                defaultPosition: .bottom,
                headerContent: {
                    VStack(alignment: .leading) {
                        HStack {
                            Image("image")
                                .resizable()
                                .frame(width: 32, height: 32)
                            VStack(alignment: .leading) {
                                Text("Hello world")
                                    .font(.caption)
                                    .fontWeight(.bold)
                                Text("4:20pm")
                                    .font(.caption2)
                            }
                            Spacer()
                            Button(action: { },
                                   label: {
                                    Image(systemName: "xmark.circle.fill")
                                        .resizable()
                                        .frame(width: 24, height: 24)
                                        .foregroundColor(Color.gray.opacity(0.5))
                                   })
                        }
                        .padding(.horizontal)
                        .padding(.bottom, 4)
                        Divider()
                    }
                    .buttonStyle(PlainButtonStyle())
                },
                bodyContent: {
                    HStack {
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.gray.opacity(0.12))
                            .frame(width: 64, height: 64)
                            .overlay(Image(systemName: "camera").foregroundColor(Color.blue))
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.gray.opacity(0.12))
                            .frame(width: 64, height: 64)
                            .overlay(Image(systemName: "sun.max.fill").foregroundColor(Color.yellow))
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.gray.opacity(0.12))
                            .frame(width: 64, height: 64)
                            .overlay(Image(systemName: "photo").foregroundColor(Color.red))
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.gray.opacity(0.12))
                            .frame(width: 64, height: 64)
                            .overlay(Image(systemName: "trash").foregroundColor(Color.green))
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.gray.opacity(0.12))
                            .frame(width: 64, height: 64)
                            .overlay(Image(systemName: "snow").foregroundColor(Color.orange))
                        Spacer()
                    }
                    .padding()
                    
                    ForEach(["Hello", "World", "Nice", "Bottom", "Sheet", "Many", "Sheets"], id: \.self) { text in
                        VStack {
                            HStack {
                                Text(text)
                                Spacer()
                                Image(systemName: "camera")
                            }
                            .frame(height: 32)
                            .padding(.horizontal, 24)
                            Divider()
                        }
                    }
                    
                    Text("This is a description with a lot of text that should wrap and fill properly repeating.This is a description with a lot of text that should wrap and fill properly repeating.This is a description with a lot of text that should wrap and fill properly repeating.This is a description with a lot of text that should wrap and fill properly repeating.")
                        .padding()
                })
        }
    }
}

Release History

  • 1.0.0
    • CHANGE: Added DefaultBottomSheet and ScaffoldBottomSheet
  • 1.0.1
    • CHANGE: Setting minimum iOS version to iOS 14. More stable
  • 1.0.2
    • CHANGE: Bug fix for compiler error and Color.black.opacity()
  • 1.0.3
    • CHANGE: Bug fix for scroll view / gesture animation glitch
    • CHANGE: Removed shouldScroll functionality on scroll view for fluid scrolling until a better solution is written.
  • 1.0.4 - 1.0.5
    • CHANGE: Minimum iOS 15 XC 13 (for now)

License

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

GitHub

link
Stars: 1
Last commit: 2 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Submit a free job ad (while I'm testing this). The analytics numbers for this website are here.

Release Notes

XC 13 minimum
2 weeks ago
  • Added iOS 15 UISheetPresentationController support

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics