Tuesday, August 9, 2022
HomeiOS Developmentios - The right way to take away duplicate favourite objects in...

ios – The right way to take away duplicate favourite objects in SwiftUI?


After I choose and favourite a personality, it will get added to my “Favorites” view and exhibits a coronary heart subsequent to the character identify within the record. Nevertheless, I am operating into a difficulty the place when I attempt to un-favorite the character, my FavoritesView provides the character quite than eradicating it. My guess is the best way I am passing my knowledge, however cannot determine it out. I’ve tried alternative ways on passing the information to attempt to repair the issue.

TabView

struct CharactersTabView: View {
   
   @StateObject var favorites = Favorites()

    var physique: some View {
        TabView {
            
            //MARK: - Character Tab
            ContentView()
                .tabItem {
                    Label("Characters", systemImage: "individual.3.fill")
                }
            
            
            //MARK: - Favorites Tab
            FavoritesView()
                .tabItem {
                    Label("Favorites", systemImage: "coronary heart.fill")
                }
                
        }//TabView
        .environmentObject(favorites)
              
    }
}

ContentView

struct ContentView: View {
    @EnvironmentObject var mannequin: CharacterViewModel
    @StateObject var favorites = Favorites()
    
    
    var previousButton: some View {
        Button("Earlier") {
            Job {
                await mannequin.previousPage()
            }
        }
        .disabled(!mannequin.hasPreviousPage)
    }
    
    var nextButton: some View {
        Button("Subsequent") {
            Job {
                await mannequin.nextPage()
            }
        }
        .disabled(!mannequin.hasNextPage)
    }


    //MARK: - Physique
    var physique: some View {
        
        NavigationView {
          
            Listing(mannequin.filteredCharacters){
                   character in
                        
                        NavigationLink {
                            CharacterDetailsView(character: character)
                        } label: {
                            HStack{
                                CharacterRowView(imageUrlString: character.picture, identify: character.identify, species: character.species)
                                
                                if favorites.incorporates(character) {
                                    Spacer()
                                    Picture(systemName: "coronary heart.fill")
                                        .accessibilityLabel("This can be a favourite character")
                                        .foregroundColor(.purple)
                                }
                            }
                        
                        }
            }
            .searchable(textual content: $mannequin.searchText, immediate: "Seek for a personality")
            .onChange(of: mannequin.searchText, carry out: { newValue in
                    Job {
                        await mannequin.fetchallCharacters()
                     }
            })
            .toolbar{
                ToolbarItem(placement: .navigationBarLeading) {
                previousButton
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                 nextButton
                }
            }
            .navigationBarTitle("Characters")
        }//Navigationview
        .job({
            await mannequin.fetchallCharacters()
        })
        .phoneOnlyNavigationView()
        .environmentObject(favorites)
        //attaching favorites to the setting on NavigationView. So each view the nagivation view presents will even acquire that Favorites instace to work with
    }
}

CharactersDetailView the place the consumer can select to favourite the character

struct CharacterDetailsView: View {
    
    //Must reference for element view by counting on the record to assign the main points. 
    var character: Character
    
    @EnvironmentObject var favorites: Favorites
   
    
    @State personal var isFavorited = false
  
    //MARK: - Computed Property
    var favoriteText: String {
        if isFavorited  {
            return "Favorited"
        } else {
            return "Favourite"
        }
    }
    
    //MARK: - Favourite Button Supplementary view
    var favoriteButton: some View {
        Button {
            isFavorited.toggle()
    
            
            if favorites.incorporates(character) {
                //If favorites incorporates a personality, we try to un-favorite and take away it
                favorites.take away(character)
            } else {
                favorites.add(character)

            }
           
        } label: {
            ZStack {
                if isFavorited == false {
                    Capsule()
                        .strokeBorder(Shade.inexperienced, lineWidth: 4)
                        .body(width: 250, peak: 50)
                        .background(
                            Capsule()
                                .fill(.inexperienced)
                                .cornerRadius(20)
                        )
                
                } else {
                    Capsule()
                        .strokeBorder(Shade.blue, lineWidth: 4)
                        .body(width: 250, peak: 50)
                        .background(
                        Capsule()
                            .fill(.blue)
                            .cornerRadius(20)
                        )
                        
                }
                
                HStack {
                    Textual content(favoriteText)
                        .foregroundColor(.white)
                    Picture(systemName: favorites.incorporates(character) ? "coronary heart.fill" : "coronary heart")
                        .foregroundColor(favorites.incorporates(character) ? .white : .white)
                        
                }
            }
        }
        .padding(.vertical)
        .onAppear {
             isFavorited = favorites.incorporates(character)
          }
    }
 
    
    //MARK: - Physique
    var physique: some View {
        ScrollView {
            VStack {
                //MARK: - Picture
                AsyncImage(url: URL(string: character.picture)) {
                    part in
                    if let picture = part.picture {
                        picture
                            .resizable()
                            .scaledToFit()
                    } else if part.error != nil {
                        Textual content("Could not add photograph")
                    } else {
                        ProgressView()
                    }
                }
            
                //MARK: - Character Particulars
                VStack(alignment: .main) {
                    Textual content(character.identify)
                        .font(.largeTitle)
                        .daring()
                        .padding(.main)
                       
                    
                    VStack(spacing: 5) {
                        SubDetailView(sfImageString: "checkmark.circle", infoText: "Standing", detailText: character.standing)
                        
                        SubDetailView(sfImageString: "individual.circle", infoText: "Species", detailText: character.species)
                       
                        SubDetailView(sfImageString: "home.circle", infoText: "Origin", detailText: character.origin.identify)
                        
                        SubDetailView(sfImageString: "mappin.circle", infoText: "Location", detailText: character.location.identify)
                         
                    }
                    .padding(.horizontal)

                }
                
           //MARK: - Favourite Button
                
            favoriteButton
                
            }
        }
    }
}

FavoritesView

struct FavoritesView: View {
    
    @EnvironmentObject var mannequin: CharacterViewModel
    @EnvironmentObject var favorites: Favorites
  
    var physique: some View {
        
       
        Listing(mannequin.filteredCharacters) { character in
            if favorites.incorporates(character) {

                HStack {
                    CharacterRowView(imageUrlString: character.picture, identify: character.identify, species: character.species)
                }
            }
        }
    }
}

Favorites logic for saving/loading knowledge

class Favorites: ObservableObject {
    personal var characters: Set<String>

    personal let saveKey = "SaveFavorites"
    
    init(){
        //load saved knowledge
        if let knowledge = UserDefaults.commonplace.knowledge(forKey: saveKey) {

            
            //Utilizing Set<String> as a result of we do not wish to retailer your complete struct, simply the id
            if let decoded = attempt? JSONDecoder().decode(Set<String>.self, from: knowledge) {
                characters = decoded
                return
            }
        }
        characters = []
    }
    
    
    func incorporates(_ character: Character) -> Bool {
        characters.incorporates(String(character.id))
    }
    
    func add(_ character: Character) {
        objectWillChange.ship()
        characters.insert(String(character.id))
        save()
    }
    
    func take away(_ character: Character) {
        objectWillChange.ship()
        characters.take away(String(character.id))
        save()
    }
    
    
    func save(){
        if let encoded = attempt? JSONEncoder().encode(characters) {
            UserDefaults.commonplace.set(encoded, forKey: saveKey)
        }
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular