I have a JSON file of "Countries" and there is a field isFavorite
which is a boolean value of false
in the JSON.
I have in my ContentView
, a list of countries and when you click on the heart beside them, it does the following:
if country.favorite {
Image(systemName: "heart.fill").foregroundColor(.red).onTapGesture {
countries[index].isFavorite.toggle()
}
} else {
Image(systemName: "heart").foregroundColor(.red).onTapGesture {
countries[index].isFavorite.toggle()
}
}
this is fine and works while in this view. When I move over to FavoritesView
, all the countries isFavorite
values are lost and set to the default false
which was in the JSON. I keep getting the view to show 'No Favorites!'. How do I retain the altered state between views?
Below is some of my code:
MainView
import SwiftUI
struct MainView: View {
@State var countries: [Country] = Bundle.main.decode("Countries.json")
var body: some View {
TabView {
ContentView(countries: $countries)
.tabItem {
Label("Menu", systemImage: "list.dash")
}
MapView()
.tabItem {
Label("Map", systemImage: "square.and.pencil")
}
FavoritesView(countries: $countries)
.tabItem {
Label("Favorites", systemImage: "square.and.pencil")
}
}
}
}
func hasFavorites() -> [Country] {
var favorites: [Country] = []
countries.forEach { country in
if country.isFavorite == true {
favorites.append(country)
}
}
return favorites
}
FavoritesView
struct FavoritesView: View {
@Binding var countries: [Country]
var body: some View {
if hasFavorites().count > 1 {
Text("test test: User has Favorites!")
} else {
Text("no favorites!")
}
}
}
CodePudding user response:
Right now, your hasFavorites
function exists outside of your views. In fact, it's unclear from the code you've included how it's accessing countries
, since, again, it is outside of the views.
I'd refactor it to be inside the view where you need it. I'd also make it a computed property and use filter
to find only the countries where isFavorite
is true
rather than doing the manual loop/append that you're doing right now.
struct FavoritesView: View {
@Binding var countries: [Country]
var favorites : [Country] {
return countries.filter { $0.isFavorite }
}
var body: some View {
if favorites.count > 1 {
Text("test test: User has Favorites!")
} else {
Text("no favorites!")
}
}
}