Connect with us

Code

Setting – Compose beautiful preference panels

Compose beautiful preference panels.

  • Simple but powerful syntax (powered by result builders).
  • Create nested pages and groups.
  • Fully searchable.
  • Native integration with SwiftUI and AppStorage.
  • Comes with pre-made components: Toggle, Button, Slider, etc…
  • Style components with native SwiftUI modifiers.
  • Show and hide components dynamically.
  • Add your own custom SwiftUI views.
  • Works on iOS and macOS.

Installation

Setting is available via the Swift Package Manager. Requires iOS 15+ or macOS Monterey and up.

https://github.com/aheze/Setting

Usage

import Setting
import SwiftUI

struct PlaygroundView: View {
    /// Setting supports `@State`, `@AppStorage`, `@Published`, and more!
    @AppStorage("isOn") var isOn = true

    var body: some View {
        /// Start things off with `SettingStack`.
        SettingStack {
            /// This is the main settings page.
            SettingPage(title: "Playground") {
                /// Use groups to group components together.
                SettingGroup(header: "Main Group") {
                    /// Use any of the pre-made components...
                    SettingToggle(title: "This value is persisted!", isOn: $isOn)

                    /// ...or define your own ones!
                    SettingCustomView {
                        Image("Logo")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 160)
                            .padding(20)
                    }

                    /// Nest `SettingPage` inside other `SettingPage`s!
                    SettingPage(title: "Advanced Settings") {
                        SettingText(title: "I show up on the next page!")
                    }
                }
            }
        }
    }
}

The result, a generated settings page. Clicking on "Advanced Settings" presents a new page.

Examples

View more examples in the example app.

struct PlaygroundView: View {
    var body: some View {
        SettingStack {
            SettingPage(title: "Playground") {
                SettingGroup {
                    SettingText(title: "Hello!")
                }
            }
        }
    }
}

Settings view rendered with "Hello!" label

SettingStack {
    SettingPage(title: "Playground") {
        SettingGroup {
            SettingText(title: "Hello!")
        }

        SettingGroup {
            SettingPage(title: "First Page") {}
                .previewIcon("star")

            SettingPage(title: "Second Page") {}
                .previewIcon("sparkles")

            SettingPage(title: "Third Page") {}
                .previewIcon("leaf.fill")
        }
    }
}

Settings view rendered with 3 row links

struct PlaygroundView: View {
    @AppStorage("isOn") var isOn = true
    @AppStorage("value") var value = Double(5)

    var body: some View {
        SettingStack {
            SettingPage(title: "Playground") {
                SettingGroup {
                    SettingToggle(title: "On", isOn: $isOn)
                }

                SettingGroup(header: "Slider") {
                    SettingSlider(
                        value: $value,
                        range: 0 ... 10
                    )
                }
            }
        }
    }
}

Settings view rendered with toggle and slider

struct PlaygroundView: View {
    @AppStorage("index") var index = 0

    var body: some View {
        SettingStack {
            SettingPage(title: "Playground") {
                SettingGroup {
                    SettingPicker(
                        title: "Picker",
                        choices: ["A", "B", "C", "D"],
                        selectedIndex: $index
                    )
                    SettingPicker(
                        title: "Picker with menu",
                        choices: ["A", "B", "C", "D"],
                        selectedIndex: $index,
                        choicesConfiguration: .init(
                            pickerDisplayMode: .menu
                        )
                    )
                }
            }
        }
    }
}

Settings view rendered with picker

SettingStack {
    SettingPage(title: "Playground") {
        SettingCustomView {
            Color.blue
                .opacity(0.1)
                .cornerRadius(12)
                .overlay {
                    Text("Put anything here!")
                        .foregroundColor(.blue)
                        .font(.title.bold())
                }
                .frame(height: 150)
                .padding(.horizontal, 16)
        }
    }
}

Settings view rendered with "Put anything here!" label

Notes

  • If multiple components have the same title, use the id parameter to make sure everything gets rendered correctly.
SettingText(id: "Announcement 1", title: "Hello!")
SettingText(id: "Announcement 2", title: "Hello!")
  • Setting comes with if-else support!
SettingToggle(title: "Turn on", isOn: $isOn)

if isOn {
    SettingText("I'm turned on!")
}
  • Wrap components in SettingCustomView to style them.
SettingCustomView {
    SettingText(title: "I'm bold!")
        .bold()
}
  • Need to store custom structs in AppStorage? Check out @IanKeen’s awesome gist!

  • You can pass in a custom SettingViewModel instance for finer control.

struct PlaygroundView: View {
    @StateObject var settingViewModel = SettingViewModel()

    var body: some View {
        SettingStack(settingViewModel: settingViewModel) {
            SettingPage(title: "Playground") {
                SettingGroup {
                    SettingText(title: "Welcome to Setting!")
                }
            }
        } customNoResultsView: {
            VStack(spacing: 20) {
                Image(systemName: "xmark")
                    .font(.largeTitle)

                Text("No results for '\(settingViewModel.searchText)'")
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

Settings view rendered with "Put anything here!" label


Community

Author Contributing Need Help?
Setting is made by aheze. All contributions are welcome. Just fork the repo, then make a pull request. Open an issue or join the Discord server. You can also ping me on Twitter.
Setting on GitHub: https://github.com/aheze/Setting
Платформа: iOS
⭐️: 877
Advertisement

Trending