Skip to content

Instantly share code, notes, and snippets.

@ejjonny
Created May 14, 2021 21:31
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ejjonny/39a88b91d9622486da8b884bf93e87e9 to your computer and use it in GitHub Desktop.
Save ejjonny/39a88b91d9622486da8b884bf93e87e9 to your computer and use it in GitHub Desktop.
Settings
import SwiftUI
struct ContentView: View {
static var toggle = false
static let settings: [Setting] = [
.push(
label: "Embedded content",
[
.text(label: "Deeper!", "Here is some embedded informational text")
]
),
.toggle(
label: "A setting to toggle",
Setting.Toggle { value in
toggle = value
} currentValue: {
toggle
}
),
.menu(
label: "Open an action sheet",
title: "Menu title",
message: "Subscript",
[
Setting.MenuOption(label: "Thing") {
print("Changed this")
},
Setting.MenuOption(label: "Other thing") {
print("Changed this other thing")
}
]
),
.text(label: "Embedded text", "Here is some informational text that will be pushed")
]
var body: some View {
NavigationView {
SettingsView(settings: Self.settings)
.navigationTitle(Text("Settings"))
}
}
}
enum Setting: Equatable, Hashable {
struct MenuOption: Equatable, Hashable {
let id = UUID()
let label: String
let action: () -> ()
static func ==(lhs: MenuOption, rhs: MenuOption) -> Bool {
lhs.id == rhs.id && lhs.label == rhs.label
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
struct Toggle: Equatable, Hashable {
let id = UUID()
let action: (Bool) -> ()
let currentValue: () -> (Bool)
static func == (lhs: Setting.Toggle, rhs: Setting.Toggle) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
case push(label: String, [Setting])
case toggle(label: String, Toggle)
case menu(label: String, title: String, message: String?, [MenuOption])
case text(label: String, String)
}
struct SettingsView: View {
let settings: [Setting]
@State var sheetPresented = false
var body: some View {
List(settings, id: \.self) { setting in
switch setting {
case let .push(label, settings):
NavigationLink(
destination:
SettingsView(settings: settings)
.navigationTitle(Text(label))
,
label: {
HStack {
Text(label)
Spacer()
}
}
)
case let .toggle(label, toggle):
HStack {
Toggle(isOn: Binding<Bool>(get: toggle.currentValue, set: toggle.action)) {
Text(label)
}
}
case let .menu(label, title, message, options):
Button(action: {
sheetPresented.toggle()
}) {
Text(label)
.actionSheet(isPresented: $sheetPresented) {
ActionSheet(title: Text(title), message: Text(optional: message), buttons: options.map { .default(Text($0.label), action: $0.action) } + [.cancel()] )
}
}
case let .text(label, text):
NavigationLink(
destination:
VStack {
Text(text)
Spacer()
}
.navigationTitle(Text(label))
,
label: {
Text(label)
}
)
}
}
}
}
extension Text {
init?(optional: String?) {
guard let string = optional else { return nil }
self.init(string)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment