2021-12-28

SwiftUI: Filtered list indices are not corresponding to new list

I have a Country model and then a JSON list of countries. I have creating the list by using a ForEach. If the search box is empty, the value of filteredCountries is just the whole list, otherwise the list only contains countries that include whats in the search box.
The problem is that when the list is filtered and I click to favorite an item, the wrong country is favorited. The indices don't match the filtered items, they still go in sequential order: 0,1,2,3 etc.

Country

import Foundation

struct Country: Codable, Identifiable {
    var id: String {image}
    let display_name: String
    let searchable_names: [String]
    let image: String
    var favorite: Bool
    var extended: Bool
}

ContentView

var filteredCountries : [Country] {
    if (searchText.isEmpty) {
        return countries;
    } else {
        return countries.filter { $0.display_name.contains(searchText) }
    }
}

          NavigationView {
                ScrollView {
                    ForEach(Array(filteredCountries.enumerated()), id: \.1.id) { (index,country) in
                        
                        LazyVStack {
                            ZStack(alignment: .bottom) {
                                Image("\(country.image)-bg")
                                    .resizable()
                                    .scaledToFit()
                                    .edgesIgnoringSafeArea(.all)
                                    .overlay(Rectangle().opacity(0.2))
                                    .mask(
                                        LinearGradient(gradient: Gradient(colors: [Color.black, Color.black.opacity(0)]), startPoint: .center, endPoint: .bottom)
                                    )
                                
                                
                                HStack {
                                    NavigationLink(
                                        destination: CountryView(country: country),
                                        label: {
                                            HStack {
                                                Image(country.image)
                                                    .resizable()
                                                    .frame(width: 50, height: 50)
                                                Text(country.display_name)
                                                    .foregroundColor(Color.black)
                                                    .padding(.leading)
                                                Spacer()
                                            }
                                            .padding(.top, 12.0)
                                            
                                        }
                                    ).buttonStyle(FlatLinkStyle())
                                    if country.favorite {
                                        Image(systemName: "heart.fill").foregroundColor(.red).onTapGesture {
                                            print(country)
                                            countries[index].favorite.toggle()
                                        }
                                        .padding(.top, 12)
                                    } else {
                                        Image(systemName: "heart").foregroundColor(.red).onTapGesture {
                                            print(country)

                                            countries[index].favorite.toggle()
                                        }
                                        .padding(.top, 12)
                                    }
                                    
                                }
                                .padding(.horizontal, 16.0)
                            }
                        }
                        .padding(.bottom, country.extended ? 220 : 0)
                        .onTapGesture {
                            withAnimation(.easeInOut(duration: 0.4)) {
                                self.countries[index].extended.toggle();
                                
                            }
                        }
                    }
                }
                .frame(maxWidth: bounds.size.width)
                .navigationTitle("Countries")
                .font(Font.custom("Avenir-Book", size: 28))


            }
            .navigationViewStyle(StackNavigationViewStyle())
            .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always), prompt: "Search Country")           


from Recent Questions - Stack Overflow https://ift.tt/3z5Qm4V
https://ift.tt/eA8V8J

No comments:

Post a Comment