Search code examples
swiftuiswiftui-list

SwiftUI - How to default the object state back to false when another object which is selected is true inside list


I am trying to update the function(isFavoriteToggle()) that when I select another object in the list the object which isFavorite state changed earlier to true get default back to false and this object isFavorite state to change to true.

For example when I select "item 1" from the list the isFavorite Boolean object state change to true. If I select "item 3" in the list then "item 1" isFavorite state change back to false and "item 3" to true.

Basically I want one Item at a time in the list to be isFavorite state to true and all other is false.

import SwiftUI

struct Items: Identifiable {
    let id = UUID().uuidString
    let name: String
    var isFavorite: Bool = false
    static var samples: [Items] = [
        Items(name: "item 1"),
        Items(name: "item 2"),
        Items(name: "item 3"),
        Items(name: "item 4"),
        Items(name: "item 5"),
        Items(name: "item 6"),
        Items(name: "item 7"),
    ]
}
import SwiftUI

struct ExampleList: View {
    @State var queryList: [Items] = Items.samples

    
    func isFavoriteToggle(element: Items) {
        guard let index = queryList.firstIndex(where: {$0.id == element.id}) else {return}
        queryList[index].isFavorite.toggle()
        
    }
   
    var body: some View {
        NavigationStack {
            List {
                ForEach($queryList) { $list in
                    Button {
                        isFavoriteToggle(element: list)
                    } label: {
                        HStack {
                            Text(list.name)
                            Spacer()
                            Image(systemName: "star.fill")
                                .foregroundColor(list.isFavorite ? Color.yellow : Color.gray)
                        }
                    }

                    
                }
            }
            .navigationTitle("Test")
            .listStyle(.plain)
            .padding()
            
            
        }

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleList()
    }
}

Appreciate your support. Thanks


Solution

  • You should try this

    struct ExampleList: View {
      
    @State var queryList: [Items] = Items.samples
    
      func isFavoriteToggle(element: Items) {
        queryList.indices.forEach { index in
            queryList[index].isFavorite = false
        }
        guard let index = queryList.firstIndex(where: { $0.id == element.id }) else { return }
        queryList[index].isFavorite = true
    }
    
    var body: some View {
        NavigationStack {
            List {
                ForEach($queryList) { $list in
                    Button {
                        isFavoriteToggle(element: list)
                    } label: {
                        HStack {
                            Text(list.name)
                            Spacer()
                            Image(systemName: "star.fill")
                                .foregroundColor(list.isFavorite ? Color.yellow : Color.gray)
                        }
                    }
                }
            }
            .navigationTitle("Test")
            .listStyle(.plain)
            .padding()
        }
    }
    }
    

    enter image description here enter image description here