{"id":17146240,"url":"https://github.com/inamiy/sherlockforms","last_synced_at":"2025-10-14T17:00:06.699Z","repository":{"id":43274986,"uuid":"459160311","full_name":"inamiy/SherlockForms","owner":"inamiy","description":"🕵️‍♂️ An elegant SwiftUI Form builder to create a searchable Settings and DebugMenu screens for iOS.","archived":false,"fork":false,"pushed_at":"2023-03-24T15:43:22.000Z","size":101,"stargazers_count":126,"open_issues_count":0,"forks_count":11,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-13T10:11:28.731Z","etag":null,"topics":["debug-menu","hud","swiftui","swiftui-form","toast"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inamiy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-14T12:50:37.000Z","updated_at":"2025-03-05T17:51:30.000Z","dependencies_parsed_at":"2025-04-13T09:33:05.741Z","dependency_job_id":"b95d53ce-6713-4cdc-885f-308df553a753","html_url":"https://github.com/inamiy/SherlockForms","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/inamiy/SherlockForms","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inamiy%2FSherlockForms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inamiy%2FSherlockForms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inamiy%2FSherlockForms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inamiy%2FSherlockForms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inamiy","download_url":"https://codeload.github.com/inamiy/SherlockForms/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inamiy%2FSherlockForms/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279019834,"owners_count":26086760,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debug-menu","hud","swiftui","swiftui-form","toast"],"created_at":"2024-10-14T21:08:12.759Z","updated_at":"2025-10-14T17:00:06.451Z","avatar_url":"https://github.com/inamiy.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🕵️‍♂️ SherlockForms\n\n\u003e What one man can invent Settings UI, another can discover its field.\n\u003e\n\u003e -- Sherlock Forms\n\nAn elegant SwiftUI Form builder to create a searchable Settings and DebugMenu screens for iOS.\n\n(Supports from iOS 14, except `.searchable` works from iOS 15)\n\n## Overview\n\n| Normal | Searching | Context Menu |\n|---|---|---|\n| \u003cimg src=\"https://user-images.githubusercontent.com/138476/153866269-62c7af4b-48ee-47b7-a66d-7c0ba2e42f07.PNG\"  width=\"300\"\u003e | \u003cimg src=\"https://user-images.githubusercontent.com/138476/153866280-ce060b33-b66a-4e5f-85bb-cf709983ba72.PNG\"  width=\"300\"\u003e | \u003cimg src=\"https://user-images.githubusercontent.com/138476/153866283-9b2718c3-9e33-43ca-94ee-5e0e3add2d25.PNG\"  width=\"300\"\u003e |\n\n| UserDefaults | App Info | Device Info |\n|---|---|---|\n| \u003cimg src=\"https://user-images.githubusercontent.com/138476/153866292-034a8f3f-7861-4a24-8010-aad52b36da42.PNG\"  width=\"300\"\u003e | \u003cimg src=\"https://user-images.githubusercontent.com/138476/153866297-102dd994-69b6-4047-87f9-a2465e7092da.PNG\"  width=\"300\"\u003e | \u003cimg src=\"https://user-images.githubusercontent.com/138476/153866301-c354f401-2982-4186-b4b1-0625728a8e8d.PNG\"  width=\"300\"\u003e |\n\nThis repository consists of 3 modules:\n\n1. `SherlockForms`: SwiftUI Form builder to enhance cell findability using iOS 15 `.searchable`.\n    - [x] Various form cells to automagically interact with `.searchable`, including Text, Button, Toggle, Picker, NavigationLink, etc.\n    - [x] \"Copy text\" from context menu by long-press\n2. `SherlockDebugForms`: Useful app/device info-views and helper methods, specifically for debugging purpose.\n    - [x] App Info view\n    - [x] Device Info view\n    - [x] UserDefaults Editor\n    - [ ] TODO: File Browser\n    - [ ] TODO: Console Logger\n3. `SherlockHUD`: Standalone, simple-to-use Notification View (Toast) UI used in `SherlockForms`\n\n## Examples\n\n### `SherlockForms` \u0026 `SherlockDebugForms`\n\nFrom [SherlockForms-Gallery app](Examples/SherlockForms-Gallery.swiftpm):\n\n```swift\nimport SwiftUI\nimport SherlockDebugForms\n\n/// NOTE: Each view that owns `SherlockForm` needs to conform to `SherlockView` protocol.\n@MainActor\nstruct RootView: View, SherlockView\n{\n    /// NOTE:\n    /// `searchText` is required for `SherlockView` protocol.\n    /// This is the only requirement to define as `@State`, and pass it to `SherlockForm`.\n    @State public var searchText: String = \"\"\n\n    @AppStorage(\"username\")\n    private var username: String = \"John Appleseed\"\n\n    @AppStorage(\"language\")\n    private var languageSelection: Int = 0\n\n    @AppStorage(\"status\")\n    private var status = Constant.Status.online\n\n    ... // Many more @AppStorage properties...\n\n    var body: some View\n    {\n        // NOTE:\n        // `SherlockForm` and `xxxCell` are where all the search magic is happening!\n        // Just treat `SherlockForm` as a normal `Form`, and use `Section` and plain SwiftUI views accordingly.\n        SherlockForm(searchText: $searchText) {\n\n            // Simple form cells.\n            Section {\n                textCell(title: \"User\", value: username)\n                arrayPickerCell(title: \"Language\", selection: $languageSelection, values: Constant.languages)\n                casePickerCell(title: \"Status\", selection: $status)\n                toggleCell(title: \"Low Power Mode\", isOn: $isLowPowerOn)\n\n                sliderCell(\n                    title: \"Speed\",\n                    value: $speed,\n                    in: 0.5 ... 2.0,\n                    step: 0.1,\n                    maxFractionDigits: 1,\n                    valueString: { \"x\\($0)\" },\n                    sliderLabel: { EmptyView() },\n                    minimumValueLabel: { Image(systemName: \"tortoise\") },\n                    maximumValueLabel: { Image(systemName: \"hare\") },\n                    onEditingChanged: { print(\"onEditingChanged\", $0) }\n                )\n\n                stepperCell(\n                    title: \"Font Size\",\n                    value: $fontSize,\n                    in: 8 ... 24,\n                    step: 1,\n                    maxFractionDigits: 0,\n                    valueString: { \"\\($0) pt\" }\n                )\n            }\n\n            // Navigation Link Cell (`navigationLinkCell`)\n            Section {\n                navigationLinkCell(\n                    title: \"UserDefaults\",\n                    destination: { UserDefaultsListView() }\n                )\n                navigationLinkCell(\n                    title: \"App Info\",\n                    destination: { AppInfoView() }\n                )\n                navigationLinkCell(\n                    title: \"Device Info\",\n                    destination: { DeviceInfoView() }\n                )\n                navigationLinkCell(title: \"Custom Page\", destination: {\n                    CustomView()\n                })\n            }\n\n            // Buttons\n            Section {\n                buttonCell(\n                    title: \"Reset UserDefaults\",\n                    action: {\n                        Helper.deleteUserDefaults()\n                        showHUD(.init(message: \"Finished resetting UserDefaults\"))\n                    }\n                )\n\n                buttonDialogCell(\n                    title: \"Delete All Contents\",\n                    dialogTitle: nil,\n                    dialogButtons: [\n                        .init(title: \"Delete All Contents\", role: .destructive) {\n                            try await deleteAllContents()\n                            showHUD(.init(message: \"Finished deleting all contents\"))\n                        },\n                        .init(title: \"Cancel\", role: .cancel) {\n                            print(\"Cancelled\")\n                        }\n                    ]\n                )\n            }\n        }\n        .navigationTitle(\"Settings\")\n        // NOTE:\n        // Use `formCopyable` here to allow ALL `xxxCell`s to be copyable.\n        .formCopyable(true)\n    }\n}\n```\n\nTo get started:\n\n1. Conform your Settings view to `protocol SherlockView`\n2. Add `@State var searchText: String` to your view\n3. Inside view's `body`, use `SherlockForm` (just like normal `Form`), and use various built-in form components:\n    - Basic built-in cells\n        - `textCell`\n        - `textFieldCell`\n        - `textEditorCell`\n        - `buttonCell`\n        - `buttonDialogCell` (iOS 15)\n        - `navigationLinkCell`\n        - `toggleCell`\n        - `arrayPickerCell`\n        - `casePickerCell`\n        - `datePickerCell`\n        - `sliderCell`\n        - `stepperCell`\n    - List\n        - `simpleList`\n        - `nestedList`\n    - More customizable cells (part of `ContainerCell`)\n        - `hstackCell`\n        - `vstackCell`\n4. (Optional) Attach `.formCellCopyable(true)` to each cell or entire form.\n5. (Optional) Attach `.enableSherlockHUD(true)` to topmost view hierarchy to enable HUD\n\nTo customize cell's internal content view rather than cell itself,\nuse `.formCellContentModifier` which may solve some troubles (e.g. context menu) when customizing cells.\n\n### `SherlockHUD`\n\n```swift\nimport SwiftUI\nimport SherlockHUD\n\n@main\nstruct MyApp: App\n{\n    var body: some Scene\n    {\n        WindowGroup {\n            NavigationView {\n                RootView()\n            }\n            .enableSherlockHUD(true) // Set at the topmost view!\n        }\n    }\n}\n\n@MainActor\nstruct RootView: View\n{\n    /// Attaching `.enableSherlockHUD(true)` to topmost view will allow using `showHUD`.\n    @Environment(\\.showHUD)\n    private var showHUD: (HUDMessage) -\u003e Void\n\n    var body: some View\n    {\n        VStack(spacing: 16) {\n            Button(\"Tap\") {\n                showHUD(HUDMessage(message: \"Hello SherlockForms!\", duration: 2, alignment: .top))\n                // alignment = top / center / bottom (default)\n                // Can also attach custom view e.g. ProgressView. See also `HUDMessage.loading`.\n            }\n        }\n        .font(.largeTitle)\n    }\n}\n```\n\nSee [SherlockHUD-Demo app](Examples/SherlockHUD-Demo.swiftpm) for more information.\n\n## Acknowledgement\n\n- [DebugMenu](https://github.com/noppefoxwolf/DebugMenu) by [@noppefoxwolf](https://github.com/noppefoxwolf) for various useful code in debugging\n- [swiftui-navigation](https://github.com/pointfreeco/swiftui-navigation) by [@pointfreeco](https://github.com/pointfreeco) for making smart state-binding techniques in SwiftUI navigation\n- [Custom HUDs in SwiftUI | FIVE STARS](https://www.fivestars.blog/articles/swiftui-hud/) by [Federico Zanetello](https://twitter.com/zntfdr) for easy-to-learn SwiftUI HUD development\n- [@inamiy](https://github.com/inamiy)'s Wife for dedicated support during this OSS development\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finamiy%2Fsherlockforms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finamiy%2Fsherlockforms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finamiy%2Fsherlockforms/lists"}