BLACK FRIDAY: Save 50% on all our Swift books and bundles! >>

Disabling items in a menu/picker

Forums > SwiftUI

I have two menus in my toolbar that will enable to a user to filter and sort the results they see in a list view.

Sometimes the selections work together, but other times they're nonsensical, and so I would like to conditionally disable certain sorting options depending on what the selected filtering option is, and vice versa.

However, disable() doesn't actually seem to DO anything in this context. Or perhaps it does behind the scenes, but that effect isn't seen in the interface; an item that should be disabled doesn't change color when it's disabled, and tapping on it will still cause a checkmark to appear.

How would I implement this functionality?

    var filteringPicker: some View {
        Menu(content: {
            Picker("Filter by...", selection: $filtering) {
                ForEach(Filtering.allCases) { option in
                    option.label
                        .disabled(option.disabled(sorting))
                }
            }
        },
        label: {
            Image(systemName: "line.horizontal.3.decrease")
        })
    }

    var sortingPicker: some View {
        Menu("Sort") {
            Picker("Sort by...", selection: $sorting) {
                ForEach(Sorting.allCases) { option in
                    option.label
                        .disabled(option.disabled(filtering))
                }
            }
        }
    }

   

Hi NCrusher74

Have you used an enum for the Filtering.allCases and Sorting.allCases?

If you put then 'items' in an array then you could add and remove the item for sorting. Not sure just spitballing.

Nigel

   

Not sure what your intent is, but you could try a computed property, something like:

    var menuItemEnabled: Bool {
        if someType.value == preferredType.value {
            return true
        }
        return false
    }

This isn't your solution, but may give you something to think about?

   

Hi @NigelGee.

Yes, I'm using enums for the two menus. A highly simplified version of what I'm trying would be this:

I have a database with several different types of records:

RecordTypeA
RecordTypeB
// etc

My Sorting enum always acts on an array of RecordTypeA to present that array in various different ways. It presents ONLY RecordTypeA.

My Filtering enum may present a filtered list of RecordTypeA objects, or it may present a list of RecordTypeB, or some other record type.

If Sorting only presents a list of RecordTypeA and the user selects a filtering option that returns a list of RecordTypeB, obviously those two selections are nonsensical together.

So if:

Sorting = RecordTypeAInAscendingOrder
Filtering = RecordTypeAFilteredBySomeCriteria

Those two options work well together. You would get the database of RecordTypeA items filtered so that the only ones shown are those that match the filter criteria, and presented in ascending order.

However:

Sorting = RecordTypeAInAscendingOrder
Filtering = RecordTypeBFilteredBySomeCriteria

Clearly those options DO NOT work together. And also, the filtering criteria for RecordTypeB is specific enough that the return shouldn't have enough matches to require sorting.

And, in fact, in this case the interface would mislead the user, because the Sorting menu would still have AscendingOrder checked, but the (short) list being presented would not, in fact, be sorted, because sorting only works on lists of RecordTypeA and what is being presented is RecordTypeB.

So it would be best to disable Sorting options when the Filtering option is going to return a list of items that aren't RecordTypeA, and vice-versa, if appropriate.

@TheTwoNotes: I had created a method on each of the enums which used the other enum as a parameter and returned true/false if the combination worked or didn't work (which is shown in the code above), but the problem is that the .disabled() modifier in the interface code (above) doesn't actually seem to be DOING anything. Which I'm sure means I'm using it incorrectly, but I don't understand how.

   

Save 50% in my Black Friday sale.

SAVE 50% This Black Friday all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.