I would like my favorites button to switch colors based on if the user favorites or unfavorites a character. I am able to change the text from "Favorite" to "Favorited" and change the color initially. If I exit the app, the button color goes back to the original color. I have logic in my computed property for the color to change but don't know how to persist it when the user open and closes the app.
Here is my code.
import SwiftUI
struct CharacterDetailsView: View {
var character: Character
@EnvironmentObject var favorites: Favorites
@State private var isFavorited = false
var favoriteText: String {
if isFavorited {
return "Favorited"
} else {
return "Favorite"
}
}
var favoriteButton: some View {
Button {
isFavorited.toggle()
if favorites.contains(character) {
//If favorites contains a character, we are trying to un-favorite and remove it
favorites.remove(character)
} else {
favorites.add(character)
}
} label: {
ZStack {
if isFavorited == false {
Capsule()
.strokeBorder(Color.green, lineWidth: 4)
.frame(width: 250, height: 50)
.background(
Capsule()
.fill(.green)
.cornerRadius(20)
)
} else {
Capsule()
.strokeBorder(Color.blue, lineWidth: 4)
.frame(width: 250, height: 50)
.background(
Capsule()
.fill(.blue)
.cornerRadius(20)
)
}
HStack {
Text(favoriteText)
.foregroundColor(.white)
Image(systemName: favorites.contains(character) ? "heart.fill" : "heart")
.foregroundColor(favorites.contains(character) ? .white : .white)
}
}
}
.padding(.vertical)
}
var body: some View {
ScrollView {
VStack {
//MARK: - Image
AsyncImage(url: URL(string: character.image)) {
phase in
if let image = phase.image {
image
.resizable()
.scaledToFit()
} else if phase.error != nil {
Text("Couldn't upload photo")
} else {
ProgressView()
}
}
VStack(alignment: .leading) {
Text(character.name)
.font(.largeTitle)
.bold()
.padding(.leading)
favoriteButton
}
}
}
}
You need to restore state from environment object where you stored provious one, like
favoriteButton
.onAppear {
isFavorite = favorites.contains(character) // << here !!
}