I want to achieve something like in the attached screenshot. I am talking about the circled chevron displaying the forward/reverse order on the selected sorting rule.
When selecting the same sort type, I want to actually use the same selected type but to reverse the order from forward to reverse or other way around.
This the menu I have right now but the button action does not execute at all.
How can I achieve this?
Menu {
Picker("Filtering", selection: viewModel.filterBinding) {
ForEach(FilterType.allCases) { filterType in
Text(filterType.rawValue)
.tag(filterType)
}
}
Divider()
Picker("Sorting", selection: viewModel.sortingBinding) {
ForEach(SortType.allCases) { sortType in
Button {
if viewModel.sortType == sortType {
viewModel.toggleSortOrder()
}
} label: {
HStack {
Text(sortType.rawValue)
Image(systemName: viewModel.sortOrder == .forward ? "chevron.up" : "chevron.down")
.opacity(viewModel.sortType == sortType ? 1 : 0)
}
}
.tag(sortType)
}
}
} label: {
Image(systemName: "line.3.horizontal.decrease.circle.fill")
}
Here are the enums you also need (probably):
enum FilterType: String, Identifiable, CaseIterable {
var id: Self { self }
case all = "Al"
case active = "Active"
case retired = "Retired"
}
enum SortType: String, Identifiable, CaseIterable {
var id: Self { self }
case brand = "by Brand"
case model = "by Model"
case distance = "by Distance"
case aquisitionDate = " by Aquisition Date"
}
2
Answers
I made an implementation to give you a hint on how you could achieve what you want without the Picker item. The issue with the Picker item, as far as my knowledge and testing go, is that it captures the tap events, and does not tell you when you tap on the same item.
Here’s what I did:
Now, it is not the best looking, of course, I did not put so much effort into that, I just wanted it to have the intended behavior. You can improve it visually as you like.
You don´t need a picker here at all. Just use the
ForEach
loop inside the menu. And useButtons
instead ofText
.e.g.: