Search code examples
swiftuiswiftui-list

Disable selection of specific items in a List


I have this simple list:

struct ContentView: View {
    
    let items = ["Item 1", "Item 2", "Item 3", "Item 4"]
    @State var selection: String? = nil
    
    var body: some View {
        
        List(selection: self.$selection) {
            ForEach(self.items, id: \.self) { item in
                Text(item)
                    .tag(item)
            }
        }
        
    }
}

Now I would like to disable the selection of specific list items, say for example "Item 2" and "Item 4". I cannot find a way to achieve this. Is it even possible?

EDIT

I already tried:

  1. Using a .onTapGesture with just a return will not work, because you can click beside the text and it will still select.

  2. Using again a .onTapGesture but with a .contentShape(Rectangle() will also not work.


Solution

  • I now solved it by creating the following modifier:

    extension View {
        func tag<V>(_ tag: V, selectable: Bool) -> some View where V : Hashable {
            Group {
                if selectable == true {
                    self.tag(tag)
                } else {
                    self.foregroundColor(.secondary)
                }
            }
        }
    }
    

    Then I can use

    List(selection: self.$selection) {
        ForEach(self.items, id: \.self) { item in
            Text(item)
                .tag(item, selectable: self.isSelectable)
            }
        }
    }
    

    Just to mention it: This is necessary, a conditional .tag modifier like .tag(self.isSelectable == true ? item : nil) doesn't work.