GithubHelp home page GithubHelp logo

jordanekay / sherlockforms Goto Github PK

View Code? Open in Web Editor NEW

This project forked from inamiy/sherlockforms

0.0 1.0 0.0 100 KB

๐Ÿ•ต๏ธโ€โ™‚๏ธ An elegant SwiftUI Form builder to create a searchable Settings and DebugMenu screens for iOS.

License: MIT License

Swift 99.64% Makefile 0.36%

sherlockforms's Introduction

๐Ÿ•ต๏ธโ€โ™‚๏ธ SherlockForms

What one man can invent Settings UI, another can discover its field.

-- Sherlock Forms

An elegant SwiftUI Form builder to create a searchable Settings and DebugMenu screens for iOS.

(Supports from iOS 14, except .searchable works from iOS 15)

Overview

Normal Searching Context Menu
UserDefaults App Info Device Info

This repository consists of 3 modules:

  1. SherlockForms: SwiftUI Form builder to enhance cell findability using iOS 15 .searchable.
    • Various form cells to automagically interact with .searchable, including Text, Button, Toggle, Picker, NavigationLink, etc.
    • "Copy text" from context menu by long-press
  2. SherlockDebugForms: Useful app/device info-views and helper methods, specifically for debugging purpose.
    • App Info view
    • Device Info view
    • UserDefaults Editor
    • TODO: File Browser
    • TODO: Console Logger
  3. SherlockHUD: Standalone, simple-to-use Notification View (Toast) UI used in SherlockForms

Examples

SherlockForms & SherlockDebugForms

From SherlockForms-Gallery app:

import SwiftUI
import SherlockDebugForms

/// NOTE: Each view that owns `SherlockForm` needs to conform to `SherlockView` protocol.
@MainActor
struct RootView: View, SherlockView
{
    /// NOTE:
    /// `searchText` is required for `SherlockView` protocol.
    /// This is the only requirement to define as `@State`, and pass it to `SherlockForm`.
    @State public var searchText: String = ""

    @AppStorage("username")
    private var username: String = "John Appleseed"

    @AppStorage("language")
    private var languageSelection: Int = 0

    @AppStorage("status")
    private var status = Constant.Status.online

    ... // Many more @AppStorage properties...

    var body: some View
    {
        // NOTE:
        // `SherlockForm` and `xxxCell` are where all the search magic is happening!
        // Just treat `SherlockForm` as a normal `Form`, and use `Section` and plain SwiftUI views accordingly.
        SherlockForm(searchText: $searchText) {

            // Simple form cells.
            Section {
                textCell(title: "User", value: username)
                arrayPickerCell(title: "Language", selection: $languageSelection, values: Constant.languages)
                casePickerCell(title: "Status", selection: $status)
                toggleCell(title: "Low Power Mode", isOn: $isLowPowerOn)

                sliderCell(
                    title: "Speed",
                    value: $speed,
                    in: 0.5 ... 2.0,
                    step: 0.1,
                    maxFractionDigits: 1,
                    valueString: { "x\($0)" },
                    sliderLabel: { EmptyView() },
                    minimumValueLabel: { Image(systemName: "tortoise") },
                    maximumValueLabel: { Image(systemName: "hare") },
                    onEditingChanged: { print("onEditingChanged", $0) }
                )

                stepperCell(
                    title: "Font Size",
                    value: $fontSize,
                    in: 8 ... 24,
                    step: 1,
                    maxFractionDigits: 0,
                    valueString: { "\($0) pt" }
                )
            }

            // Navigation Link Cell (`navigationLinkCell`)
            Section {
                navigationLinkCell(
                    title: "UserDefaults",
                    destination: { UserDefaultsListView() }
                )
                navigationLinkCell(
                    title: "App Info",
                    destination: { AppInfoView() }
                )
                navigationLinkCell(
                    title: "Device Info",
                    destination: { DeviceInfoView() }
                )
                navigationLinkCell(title: "Custom Page", destination: {
                    CustomView()
                })
            }

            // Buttons
            Section {
                buttonCell(
                    title: "Reset UserDefaults",
                    action: {
                        Helper.deleteUserDefaults()
                        showHUD(.init(message: "Finished resetting UserDefaults"))
                    }
                )

                buttonDialogCell(
                    title: "Delete All Contents",
                    dialogTitle: nil,
                    dialogButtons: [
                        .init(title: "Delete All Contents", role: .destructive) {
                            try await deleteAllContents()
                            showHUD(.init(message: "Finished deleting all contents"))
                        },
                        .init(title: "Cancel", role: .cancel) {
                            print("Cancelled")
                        }
                    ]
                )
            }
        }
        .navigationTitle("Settings")
        // NOTE:
        // Use `formCopyable` here to allow ALL `xxxCell`s to be copyable.
        .formCopyable(true)
    }
}

To get started:

  1. Conform your Settings view to protocol SherlockView
  2. Add @State var searchText: String to your view
  3. Inside view's body, use SherlockForm (just like normal Form), and use various built-in form components:
    • Basic built-in cells
      • textCell
      • textFieldCell
      • textEditorCell
      • buttonCell
      • buttonDialogCell (iOS 15)
      • navigationLinkCell
      • toggleCell
      • arrayPickerCell
      • casePickerCell
      • datePickerCell
      • sliderCell
      • stepperCell
    • List
      • simpleList
      • nestedList
    • More customizable cells (part of ContainerCell)
      • hstackCell
      • vstackCell
  4. (Optional) Attach .formCellCopyable(true) to each cell or entire form.
  5. (Optional) Attach .enableSherlockHUD(true) to topmost view hierarchy to enable HUD

To customize cell's internal content view rather than cell itself, use .formCellContentModifier which may solve some troubles (e.g. context menu) when customizing cells.

SherlockHUD

import SwiftUI
import SherlockHUD

@main
struct MyApp: App
{
    var body: some Scene
    {
        WindowGroup {
            NavigationView {
                RootView()
            }
            .enableSherlockHUD(true) // Set at the topmost view!
        }
    }
}

@MainActor
struct RootView: View
{
    /// Attaching `.enableSherlockHUD(true)` to topmost view will allow using `showHUD`.
    @Environment(\.showHUD)
    private var showHUD: (HUDMessage) -> Void

    var body: some View
    {
        VStack(spacing: 16) {
            Button("Tap") {
                showHUD(HUDMessage(message: "Hello SherlockForms!", duration: 2, alignment: .top))
                // alignment = top / center / bottom (default)
                // Can also attach custom view e.g. ProgressView. See also `HUDMessage.loading`.
            }
        }
        .font(.largeTitle)
    }
}

See SherlockHUD-Demo app for more information.

Acknowledgement

License

MIT

sherlockforms's People

Contributors

inamiy avatar

Watchers

 avatar

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.