NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

How could I make a button change the value of a Bool in SwiftUI?

Forums > SwiftUI

I am building an app that will store multiple Nintendo consoles and their details (kinda like Mactracker but for Nintendo stuff).

I have a favourites view that stores only if consoles that only have a bool variable set to true, the consoles are stored in a consoles file which will be showed below. This is all working fine but I want to make a button that changes the value of the bool from false to true and then from true to false if its tapped again.

I tried using .toggle() but couldn't get anywhere.

I want the console in which I press the "Add to favorites button" to save it in the favorites view. Which means I need to change a favourites bool in the console list to true. When I press on the same button again I want it to be removed from the favorites view

The button is in the ConsoleDetailView. I have a main menu which has the multiple categories including the favorites category which takes me to the favourites view.

Here's the main menu (The else if's help me put them in different sections so don't mind them):

import SwiftUI

struct MainMenu: View {
    // Use categories ordered by alphabetical order
    var categories = ConsoleList.categories.sorted(by: {$0.key < $1.key})
    var con = ConsoleList.consoles

    var body: some View {
        // Navigation view for all types
        NavigationView{
            List {
                Section {
                    NavigationLink {
                        CurrentConsoles(con: con)
                    } label: {
                        Image(systemName: "folder")
                            .foregroundColor(.red)
                        Text("Current Consoles")
                        .fontWeight(.semibold)}
                    NavigationLink {
                        Favorites(con: con)
                    } label: {
                        //Favorites part
                        Image(systemName: "heart")
                            .foregroundColor(.red)
                        Text("Favorites")
                        .fontWeight(.semibold)}
                }
                Section {
                    ForEach(categories, id: \.key) {  category in
                        if category.key == "Home Consoles"{
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }else if category.key == "Hybrid"{
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }else if category.key == "Color TV Game"{
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }else if category.key == "Other"{
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }
                    }
                }
                Section {
                    ForEach(categories, id: \.key) {  category in
                        if category.key == "Nintendo DS / 3DS"{
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }else if category.key == "GameBoys"{
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }else if category.key == "Game & Watch" {
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }else if category.key == "iQue" {
                            NavigationLink(destination: ConsoleMenu(con: category.value), label:{
                                Image(systemName: "folder")
                                    .foregroundColor(.red)
                                Text(category.key)
                                    .fontWeight(.semibold)
                            })
                        }
                    }
                }
            }
            .navigationTitle("Famitrack")

        }
    }
}

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

Here's the favourites view:

import SwiftUI

struct Favorites: View {

    var con: [ConsoleDetails]
    var body: some View {
        //list of consoles
        List(con){ cons in
            if cons.favorites {
                NavigationLink(destination: ConsoleDetailView(con: cons), label:{
                    Image(cons.imgName)
                        .resizable()
                        .scaledToFit()
                        .frame(width: 50, height: 50)
                        .cornerRadius(4)
                        .padding(.vertical, 4)

                    VStack (alignment: .leading){
                        if cons.category == "Game & Watch" {
                            Text(cons.consoleName)
                                .fontWeight(.semibold)
                            Text(cons.mostSoldGame)
                                .font(.subheadline)
                        }else{
                            Text(cons.consoleName)
                                .fontWeight(.semibold)
                            Text(cons.category)
                                .font(.subheadline)
                        }
                    }
                }).navigationTitle("Favorites")
            }
        }
    }
}

struct favorites_Previews: PreviewProvider {
    static var previews: some View {
        Favorites(con: ConsoleList.consoles)
    }
}

Here's the Console Detail View with the favorites button near the end:

import SwiftUI

struct ConsoleDetailView: View {

    @State var con: ConsoleDetails

    var body: some View {
        VStack{
            HStack{
                Spacer()
                Image(con.imgName)
                    .resizable()
                    .scaledToFit()
                    .frame( height: 60)
                VStack(alignment: .leading) {
                    Text(con.consoleName)
                        .font(.title2)
                        .fontWeight(.semibold)
                    if con.category == "Game & Watch" {
                        Text(con.mostSoldGame)
                    }
                }
                Spacer()
            }
            List{
                if con.category == "Game & Watch"{
                    Text("Release Date: \(con.ReleaseDate)")
                    Text("Initial Price: $\(con.initialPrice)")
                    Text("Discontinuation Date: \(con.Discontinuation)")
                    Text("""
                        Estimated Price Today (07.2022):
                        \(con.estimatedPricedToday)
                        """)
                    Text("Game & Watch category: \(con.mostSoldGame)")
                    Text("Batteries: \(con.cables)")
                    Text("""
                        Processor:
                        \(con.processor)
                        """)
                    Text("""
                    Screen Size:
                    \(con.screenSize)
                    """)
                    if con.dims != ""{
                        Text("""
                        Dimensions:
                        \(con.dims)
                        """)
                    }
                    //
                }else{
                    Text("Release Date: \(con.ReleaseDate)")
                    if con.consoleName == "Famicom" {
                        Text("πŸ‡―πŸ‡΅ Initial Price: \(con.initialPrice)")
                    } else if con.consoleName == "Super Famicom" {
                        Text("πŸ‡―πŸ‡΅ Initial Price: \(con.initialPrice)")
                    } else {
                        Text("πŸ‡ΊπŸ‡Έ Initial Price: $\(con.initialPrice)")
                    }
                    Text("Discontinuation Date: \(con.Discontinuation)")
                    Text("""
                        πŸ‡ΊπŸ‡Έ Estimated Price Today (07.2022):
                        \(con.estimatedPricedToday)
                        """)
                    Text("""
                        Best Selling Game:
                        \(con.mostSoldGame)
                        """)
                    Text("Ports: \(con.cables)")
                    Text("""
                        Processor:
                        \(con.processor)
                        """)
                    if con.screenSize != ""{
                        Text("""
                        Screen Size:
                        \(con.screenSize)
                        """)
                    }
                    if con.dims != ""{
                        Text("""
                        Dimensions:
                        \(con.dims)
                        """)
                    }
                    //heres the button
                    Button("Add to favorites") {
                        con.favorites.toggle()
                    }

                }

            }.listStyle(.grouped)

        }

    }

    struct ConsoleDetailView_Previews: PreviewProvider {
        static var previews: some View {
            ConsoleDetailView(con: ConsoleList.consoles.first!)

        }
    }

}

Here's the list of all consoles (but I put one to save space):

import Foundation
import SwiftUI

struct ConsoleDetails: Identifiable{
    let id = UUID()
    var imgName: String = ""
    var consoleName: String = ""
    var mostSoldGame: String = ""
    var initialPrice: String = ""
    var ReleaseDate: String = ""
    var Discontinuation: String = ""
    var category: String = ""
    var estimatedPricedToday: String = ""
    var cables: String = ""
    var processor: String = ""
    var screenSize: String = ""
    var dims: String = ""
    var favorites: Bool = false
    var discontinued: Bool = true
    var isHandheld: Bool = true
}

struct ConsoleList{
    //The consoles list but I'll only put one to save space
    static var categories = Dictionary(grouping: consoles, by: {$0.category } )
    static var consoles = [
        //Current Consoles
        ConsoleDetails(imgName: "NS_OG",
                       consoleName: "Nintendo Switch",
                       mostSoldGame: "Mario Kart 8 Deluxe",
                       initialPrice: "299.99",
                       ReleaseDate: "Mar 3, 2017",
                       Discontinuation: "Still Available",
                       category: "Hybrid",
                       estimatedPricedToday: "$200-250 used",
                       cables: "HDMI, USB Type-C, Micro SD card slot, 3x USB Ports",
                       processor: "Nvidia Tegra X1",
                       screenSize: """
                       Capacitive touch screen
                       6.2 inch LCD Screen
                       1280 x 720
                       """,
                       dims: """
                          W: 9.40\"
                          H: 4.01\"
                          D: 0.55\"
                          """,
                       favorites: false,
                       discontinued: false,
                       isHandheld: true),

   

@Bnerd  

You .toggle() the Bool in the ConsoleDetailView but do you save the change? If not, you will never see the difference in the Favorites view.

   

Hacking with Swift is sponsored by Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.