From 6db252a37d623b22eb03308ba13ef2ad032a8c23 Mon Sep 17 00:00:00 2001 From: mehdi negahban Date: Sun, 7 Apr 2024 01:07:45 +0330 Subject: [PATCH 1/6] add icon to pickerview --- Sources/Views/SettingPicker.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Sources/Views/SettingPicker.swift b/Sources/Views/SettingPicker.swift index f255d41..2d7cbbc 100644 --- a/Sources/Views/SettingPicker.swift +++ b/Sources/Views/SettingPicker.swift @@ -22,6 +22,7 @@ public struct SettingPicker: View, Setting { public var verticalPadding = CGFloat(14) public var horizontalPadding: CGFloat? public var choicesConfiguration = ChoicesConfiguration() + public var iconArray: [SettingIcon]? // Add property for array of icons public init( id: AnyHashable? = nil, @@ -33,8 +34,11 @@ public struct SettingPicker: View, Setting { horizontalSpacing: CGFloat = CGFloat(12), verticalPadding: CGFloat = CGFloat(14), horizontalPadding: CGFloat? = nil, - choicesConfiguration: ChoicesConfiguration = ChoicesConfiguration() + choicesConfiguration: ChoicesConfiguration = ChoicesConfiguration(), + iconArray: [SettingIcon]? = nil // Add parameter for array of icons ) { + + self.id = id self.icon = icon self.title = title @@ -45,6 +49,7 @@ public struct SettingPicker: View, Setting { self.verticalPadding = verticalPadding self.horizontalPadding = horizontalPadding self.choicesConfiguration = choicesConfiguration + self.iconArray = iconArray // Assign array of icons } public enum PickerDisplayMode { @@ -138,13 +143,15 @@ struct SettingPickerView: View { var body: some View { switch choicesConfiguration.pickerDisplayMode { - case .navigation: + case .navigation: Button { isActive = true } label: { HStack(spacing: horizontalSpacing) { - if let icon { - SettingIconView(icon: icon) + if let iconArray = iconArray { + ForEach(iconArray) { icon in // Loop through array of icons + SettingIconView(icon: icon) + } } Text(title) @@ -179,6 +186,7 @@ struct SettingPickerView: View { } .opacity(0) } + case .menu: HStack(spacing: horizontalSpacing) { From 6f1f4fcad0f0179d1fd41d966b81416f3843dc36 Mon Sep 17 00:00:00 2001 From: mehdi negahban Date: Sun, 7 Apr 2024 01:11:40 +0330 Subject: [PATCH 2/6] add action to toggle --- Sources/Views/SettingToggle.swift | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Sources/Views/SettingToggle.swift b/Sources/Views/SettingToggle.swift index 39fc909..c4a6563 100644 --- a/Sources/Views/SettingToggle.swift +++ b/Sources/Views/SettingToggle.swift @@ -8,16 +8,14 @@ import SwiftUI -/** - A simple toggle. - */ public struct SettingToggle: View, Setting { public var id: AnyHashable? public var title: String @Binding public var isOn: Bool public var horizontalSpacing = CGFloat(12) public var verticalPadding = CGFloat(14) - public var horizontalPadding: CGFloat? = nil + public var horizontalPadding = CGFloat(16) + public var onChange: ((Bool) -> Void)? // Add onChange closure public init( id: AnyHashable? = nil, @@ -25,7 +23,8 @@ public struct SettingToggle: View, Setting { isOn: Binding, horizontalSpacing: CGFloat = CGFloat(12), verticalPadding: CGFloat = CGFloat(14), - horizontalPadding: CGFloat? = nil + horizontalPadding: CGFloat = CGFloat(16), + onChange: ((Bool) -> Void)? = nil // Initialize onChange closure ) { self.id = id self.title = title @@ -33,6 +32,7 @@ public struct SettingToggle: View, Setting { self.horizontalSpacing = horizontalSpacing self.verticalPadding = verticalPadding self.horizontalPadding = horizontalPadding + self.onChange = onChange // Assign onChange closure } public var body: some View { @@ -41,20 +41,20 @@ public struct SettingToggle: View, Setting { isOn: $isOn, horizontalSpacing: horizontalSpacing, verticalPadding: verticalPadding, - horizontalPadding: horizontalPadding + horizontalPadding: horizontalPadding, + onChange: onChange // Pass onChange closure to SettingToggleView ) } } struct SettingToggleView: View { - @Environment(\.edgePadding) var edgePadding - let title: String @Binding var isOn: Bool var horizontalSpacing = CGFloat(12) var verticalPadding = CGFloat(14) - var horizontalPadding: CGFloat? = nil + var horizontalPadding = CGFloat(16) + var onChange: ((Bool) -> Void)? // Receive onChange closure var body: some View { HStack(spacing: horizontalSpacing) { @@ -65,8 +65,11 @@ struct SettingToggleView: View { Toggle("", isOn: $isOn) .labelsHidden() + .onChange(of: isOn, perform: { newValue in + onChange?(newValue) // Call onChange closure + }) } - .padding(.horizontal, horizontalPadding ?? edgePadding) + .padding(.horizontal, horizontalPadding) .accessibilityElement(children: .combine) } } From bda5d05904f684ccee30ac2e869fe4c03448379e Mon Sep 17 00:00:00 2001 From: mehdi negahban Date: Sun, 7 Apr 2024 16:05:06 +0330 Subject: [PATCH 3/6] make settingPicker to Default --- Sources/Views/SettingPicker.swift | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Sources/Views/SettingPicker.swift b/Sources/Views/SettingPicker.swift index 2d7cbbc..f255d41 100644 --- a/Sources/Views/SettingPicker.swift +++ b/Sources/Views/SettingPicker.swift @@ -22,7 +22,6 @@ public struct SettingPicker: View, Setting { public var verticalPadding = CGFloat(14) public var horizontalPadding: CGFloat? public var choicesConfiguration = ChoicesConfiguration() - public var iconArray: [SettingIcon]? // Add property for array of icons public init( id: AnyHashable? = nil, @@ -34,11 +33,8 @@ public struct SettingPicker: View, Setting { horizontalSpacing: CGFloat = CGFloat(12), verticalPadding: CGFloat = CGFloat(14), horizontalPadding: CGFloat? = nil, - choicesConfiguration: ChoicesConfiguration = ChoicesConfiguration(), - iconArray: [SettingIcon]? = nil // Add parameter for array of icons + choicesConfiguration: ChoicesConfiguration = ChoicesConfiguration() ) { - - self.id = id self.icon = icon self.title = title @@ -49,7 +45,6 @@ public struct SettingPicker: View, Setting { self.verticalPadding = verticalPadding self.horizontalPadding = horizontalPadding self.choicesConfiguration = choicesConfiguration - self.iconArray = iconArray // Assign array of icons } public enum PickerDisplayMode { @@ -143,15 +138,13 @@ struct SettingPickerView: View { var body: some View { switch choicesConfiguration.pickerDisplayMode { - case .navigation: + case .navigation: Button { isActive = true } label: { HStack(spacing: horizontalSpacing) { - if let iconArray = iconArray { - ForEach(iconArray) { icon in // Loop through array of icons - SettingIconView(icon: icon) - } + if let icon { + SettingIconView(icon: icon) } Text(title) @@ -186,7 +179,6 @@ struct SettingPickerView: View { } .opacity(0) } - case .menu: HStack(spacing: horizontalSpacing) { From dd4f2892018cf09311d74c0904dc16428fd392fb Mon Sep 17 00:00:00 2001 From: mehdi negahban Date: Mon, 8 Apr 2024 13:46:38 +0330 Subject: [PATCH 4/6] add pull request to repo --- Sources/Views/SettingToggle.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Sources/Views/SettingToggle.swift b/Sources/Views/SettingToggle.swift index c4a6563..4c0c53d 100644 --- a/Sources/Views/SettingToggle.swift +++ b/Sources/Views/SettingToggle.swift @@ -12,6 +12,7 @@ public struct SettingToggle: View, Setting { public var id: AnyHashable? public var title: String @Binding public var isOn: Bool + public var icon: SettingIcon? public var horizontalSpacing = CGFloat(12) public var verticalPadding = CGFloat(14) public var horizontalPadding = CGFloat(16) @@ -19,6 +20,7 @@ public struct SettingToggle: View, Setting { public init( id: AnyHashable? = nil, + icon: SettingIcon? = nil, title: String, isOn: Binding, horizontalSpacing: CGFloat = CGFloat(12), @@ -27,6 +29,7 @@ public struct SettingToggle: View, Setting { onChange: ((Bool) -> Void)? = nil // Initialize onChange closure ) { self.id = id + self.icon = icon self.title = title self._isOn = isOn self.horizontalSpacing = horizontalSpacing @@ -37,6 +40,7 @@ public struct SettingToggle: View, Setting { public var body: some View { SettingToggleView( + icon: icon, title: title, isOn: $isOn, horizontalSpacing: horizontalSpacing, @@ -48,6 +52,7 @@ public struct SettingToggle: View, Setting { } struct SettingToggleView: View { + let icon: SettingIcon? let title: String @Binding var isOn: Bool @@ -58,6 +63,10 @@ struct SettingToggleView: View { var body: some View { HStack(spacing: horizontalSpacing) { + if let icon { + SettingIconView(icon: icon) + } + Text(title) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) From a9c04cf92506f0919e1365bee2d54fb47ddab9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9D=82?= Date: Sun, 26 Jan 2025 03:12:49 +0100 Subject: [PATCH 5/6] Update SettingToggle - impl. edgePadding setter, fix. icon padding issue via nillable horizontalPadding _ref aheze/Setting#42 This update fixes SettingToggle implementing Icons among other functionality - impl: edgePadding setter (optional) via env_var, otherwise uses horizontalPadding (default) - fixes: Icon padding issue (ref via nillable horizontalPadding (ref. https://github.com/aheze/Setting/pull/38#issuecomment-2614139662, covers aheze/Setting#38, aheze/Setting#37 - impl: SettingToggle extension supporting `.icon(...)` methods - impl: SettingToggle `onChange(...)` event handler, triggering when toggle is switched on/off --- Sources/Views/SettingToggle.swift | 34 +++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/Sources/Views/SettingToggle.swift b/Sources/Views/SettingToggle.swift index 4c0c53d..8bbcec2 100644 --- a/Sources/Views/SettingToggle.swift +++ b/Sources/Views/SettingToggle.swift @@ -15,7 +15,7 @@ public struct SettingToggle: View, Setting { public var icon: SettingIcon? public var horizontalSpacing = CGFloat(12) public var verticalPadding = CGFloat(14) - public var horizontalPadding = CGFloat(16) + public var horizontalPadding: CGFloat? = nil public var onChange: ((Bool) -> Void)? // Add onChange closure public init( @@ -25,7 +25,7 @@ public struct SettingToggle: View, Setting { isOn: Binding, horizontalSpacing: CGFloat = CGFloat(12), verticalPadding: CGFloat = CGFloat(14), - horizontalPadding: CGFloat = CGFloat(16), + horizontalPadding: CGFloat? = nil, onChange: ((Bool) -> Void)? = nil // Initialize onChange closure ) { self.id = id @@ -52,21 +52,23 @@ public struct SettingToggle: View, Setting { } struct SettingToggleView: View { + @Environment(\.edgePadding) var edgePadding + let icon: SettingIcon? let title: String @Binding var isOn: Bool var horizontalSpacing = CGFloat(12) var verticalPadding = CGFloat(14) - var horizontalPadding = CGFloat(16) + var horizontalPadding: CGFloat? = nil var onChange: ((Bool) -> Void)? // Receive onChange closure var body: some View { HStack(spacing: horizontalSpacing) { if let icon { - SettingIconView(icon: icon) + SettingIconView(icon: icon) } - + Text(title) .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) @@ -78,7 +80,27 @@ struct SettingToggleView: View { onChange?(newValue) // Call onChange closure }) } - .padding(.horizontal, horizontalPadding) + .padding(.horizontal, horizontalPadding ?? edgePadding) .accessibilityElement(children: .combine) } } + +public extension SettingToggle { + func icon(_ icon: String, color: Color = .blue) -> SettingToggle { + var toggle = self + toggle.icon = .system(icon: icon, backgroundColor: color) + return toggle + } + + func icon(_ icon: String, foregroundColor: Color = .white, backgroundColor: Color = .blue) -> SettingToggle { + var toggle = self + toggle.icon = .system(icon: icon, foregroundColor: foregroundColor, backgroundColor: backgroundColor) + return toggle + } + + func icon(icon: SettingIcon) -> SettingToggle { + var toggle = self + toggle.icon = icon + return toggle + } +} From d696cec1323b91c17efd5110f0a71a7ac3eebee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9D=82?= Date: Sun, 26 Jan 2025 03:41:01 +0100 Subject: [PATCH 6/6] Update SettingExample/PreferencesView - added example rendering SettingToggle w. Icon + onChange(...) event _ref aheze#42 This change updates the Setting/SettingExample/PreferencesView showing how to use added icon support on SettingToggle, alongside the sample code which tracks toggle switch events and trigger onChange handler via closure Added Toggle switch example is rendered in "Extras" SettingGroup in "Preferences" tab: - SettingToggle `toggleIcon` (bool-based @AppStorage bindings) - SettingToggle `.icon(...)` example - SettingToggle `onChange(...)` example @duraki via _ref aheze#42 --- Example/SettingExample/PreferencesView.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Example/SettingExample/PreferencesView.swift b/Example/SettingExample/PreferencesView.swift index b6cda58..525c358 100644 --- a/Example/SettingExample/PreferencesView.swift +++ b/Example/SettingExample/PreferencesView.swift @@ -19,6 +19,7 @@ class PreferencesViewModel: ObservableObject { @AppStorage("notificationIndex") var notificationIndex = 0 @AppStorage("notificationPromo") var notificationPromo = true @AppStorage("notificationUpdates") var notificationUpdates = true + @AppStorage("toggleIcon") var toggleUpdate = true @AppStorage("color") var color = 0xFF3100 @AppStorage("text") var text = "" @Published var showingAlert = false @@ -240,6 +241,17 @@ struct PreferencesView: View { .icon(icon: .system(icon: "sparkles", backgroundColor: Color.pink)) .indicator("face.smiling") } + + SettingGroup { + SettingToggle( + icon: .system(icon: "globe", backgroundColor: Color.pink), + title: "Toggle with Icon", + isOn: $model.toggleUpdate, + onChange: { _ in + print("Toggle is switched: \($model.toggleUpdate)") + } + ) + } } .previewIcon(icon: .system(icon: "ellipsis", backgroundColor: Color.teal)) }