Skip to content

Commit

Permalink
Make menu picker use Toggle instead to stay inline with style
Browse files Browse the repository at this point in the history
  • Loading branch information
Supereg committed Jan 19, 2025
1 parent 063e809 commit 1c4be3f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
9 changes: 0 additions & 9 deletions Sources/SpeziViews/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{
"sourceLanguage" : "en",
"strings" : {
"" : {

},
"%lld selected" : {

},
Expand Down Expand Up @@ -34,9 +31,6 @@
},
"Dismiss" : {

},
"Empty" : {

},
"Error" : {
"comment" : "View State default error title",
Expand Down Expand Up @@ -111,9 +105,6 @@
},
"Option %u" : {

},
"Test" : {

}
},
"version" : "1.0"
Expand Down
44 changes: 35 additions & 9 deletions Sources/SpeziViews/Views/Controls/OptionSetPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import SwiftUI


/// The view style for an `OptionSetPicker`.
public enum OptionSetPickerStyle {
/// The picker is rendered inline (e.g., in a List view).
Expand Down Expand Up @@ -64,6 +65,7 @@ public struct OptionSetPicker<Label: View, Value: OptionSet & PickerValue>: View

@Binding private var selection: Value


private var selectionCount: Int {
Value.allCases.count { value in
selection.contains(value)
Expand Down Expand Up @@ -99,9 +101,10 @@ public struct OptionSetPicker<Label: View, Value: OptionSet & PickerValue>: View
case .menu:
Menu {

Check failure on line 102 in Sources/SpeziViews/Views/Controls/OptionSetPicker.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package watchOS / Test using xcodebuild or run fastlane

'Menu' is unavailable in watchOS

Check failure on line 102 in Sources/SpeziViews/Views/Controls/OptionSetPicker.swift

View workflow job for this annotation

GitHub Actions / Build and Test Swift Package watchOS / Test using xcodebuild or run fastlane

'init(content:label:)' is unavailable in watchOS
ForEach(Value.allCases, id: \.self) { value in
button(for: value)
toggle(for: value)
}
} label: {
// TODO: use toggles instead!

Check failure on line 107 in Sources/SpeziViews/Views/Controls/OptionSetPicker.swift

View workflow job for this annotation

GitHub Actions / SwiftLint / SwiftLint / SwiftLint

Todo Violation: TODOs should be resolved (use toggles instead!) (todo)
LabeledContent {
HStack {
if selectionCount < 2 {
Expand Down Expand Up @@ -168,16 +171,11 @@ public struct OptionSetPicker<Label: View, Value: OptionSet & PickerValue>: View
}
}


@ViewBuilder
private func button(for value: Value) -> some View {
Button {
if selection.contains(value) {
if selection != value || allowEmptySelection {
selection.remove(value)
}
} else {
selection.insert(value)
}
buttonAction(for: value)
} label: {
HStack {
Text(value.localizedStringResource)
Expand All @@ -192,6 +190,32 @@ public struct OptionSetPicker<Label: View, Value: OptionSet & PickerValue>: View
}
}
}

@ViewBuilder
private func toggle(for value: Value) -> some View {
let binding = Binding {
selection.contains(value)
} set: { newValue in
guard newValue != selection.contains(value) else {
return
}
buttonAction(for: value)
}

Toggle(isOn: binding) {
Text(value.localizedStringResource)
}
}

private func buttonAction(for value: Value) {
if selection.contains(value) {
if selection != value || allowEmptySelection {
selection.remove(value)
}
} else {
selection.insert(value)
}
}
}


Expand All @@ -215,15 +239,17 @@ extension PreviewLayout {
}
}


#Preview {
@Previewable @State var selection: PreviewLayout.Options = []
@Previewable @State var picker: String = ""

List {
OptionSetPicker("Test", selection: $selection)
Picker("Test", selection: $picker) {
Picker("Test", selection: $picker) { // for style comparison
Text("Empty").tag("")
}
OptionSetPicker("Test", selection: $selection, style: .inline, allowEmptySelection: true)
}
}
#endif

0 comments on commit 1c4be3f

Please sign in to comment.