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)) } diff --git a/Sources/Views/SettingToggle.swift b/Sources/Views/SettingToggle.swift index 39fc909..8bbcec2 100644 --- a/Sources/Views/SettingToggle.swift +++ b/Sources/Views/SettingToggle.swift @@ -8,56 +8,67 @@ 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 icon: SettingIcon? public var horizontalSpacing = CGFloat(12) public var verticalPadding = CGFloat(14) public var horizontalPadding: CGFloat? = nil + public var onChange: ((Bool) -> Void)? // Add onChange closure public init( id: AnyHashable? = nil, + icon: SettingIcon? = nil, title: String, isOn: Binding, horizontalSpacing: CGFloat = CGFloat(12), verticalPadding: CGFloat = CGFloat(14), - horizontalPadding: CGFloat? = nil + horizontalPadding: CGFloat? = nil, + onChange: ((Bool) -> Void)? = nil // Initialize onChange closure ) { self.id = id + self.icon = icon self.title = title self._isOn = isOn self.horizontalSpacing = horizontalSpacing self.verticalPadding = verticalPadding self.horizontalPadding = horizontalPadding + self.onChange = onChange // Assign onChange closure } public var body: some View { SettingToggleView( + icon: icon, title: title, 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 icon: SettingIcon? let title: String @Binding var isOn: Bool var horizontalSpacing = CGFloat(12) var verticalPadding = CGFloat(14) var horizontalPadding: CGFloat? = nil + var onChange: ((Bool) -> Void)? // Receive onChange closure 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) @@ -65,8 +76,31 @@ struct SettingToggleView: View { Toggle("", isOn: $isOn) .labelsHidden() + .onChange(of: isOn, perform: { newValue in + onChange?(newValue) // Call onChange closure + }) } .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 + } +}