zummer
zummer

Reputation: 15

How to make every button by pressing change its own background color in SwiftUI?

I want to make every button change its colour when I tap on it and change colour back when I tap again. So I made a boolean didTap and according to its value, it should change its background.

The code at the moment changes every button background. As I understand from other posts, this system for Buttons is not working perfectly.

What to do? How to get the result i need? Should I use something else(not Button) ? Should I use something like this didTapB1 and so on?(Seems its gonna be a long code if using that?)

Bingo Buttons

import SwiftUI

var headLine = ["B", "I", "N", "G", "O"]
var numB = ["5","9","11","15","9"]
var numI = ["16","19","21","25","22"]
var numN = ["35","39","41","45","42"]
var numG = ["55","59","61","57","52"]
var numO = ["66","69","71","75","72"]

struct TestView: View {

@State private var didTap:Bool = false
 var body: some View {


    ZStack {
        Color.orange
    .edgesIgnoringSafeArea(.all)


    HStack {

        VStack {
            Text("B")
                ForEach(numB, id: \.self) { tekst in
                   Button(action: {
                    if self.didTap == false {
                        self.didTap = true
                    } else {
                        self.didTap = false
                    }

                        }) {
                    Text(tekst)
                        .padding()
                        .background(self.didTap ? Color.red : Color.black)
                            .clipShape(Circle())
                }
            }
        }
        VStack {
            Text("I")
                ForEach(numI, id: \.self) { tekst in
                   Button(action: {
                    if self.didTap == false {
                        self.didTap = true
                    } else {
                        self.didTap = false
                    }

                        }) {
                    Text(tekst)
                        .padding()
                        .background(self.didTap ? Color.red : Color.black)
                            .clipShape(Circle())
                }
            }
        }
    VStack {
        Text("N")
            ForEach(numN, id: \.self) { tekst in
               Button(action: {
                if self.didTap == false {
                    self.didTap = true
                } else {
                    self.didTap = false
                }

                    }) {
                Text(tekst)
                    .padding()
                    .background(self.didTap ? Color.red : Color.black)
                        .clipShape(Circle())
            }
        }
    }
        VStack {
            Text("G")
                ForEach(numG, id: \.self) { tekst in
                   Button(action: {
                    if self.didTap == false {
                        self.didTap = true
                    } else {
                        self.didTap = false
                    }

                        }) {
                    Text(tekst)
                        .padding()
                        .background(self.didTap ? Color.red : Color.black)
                            .clipShape(Circle())
                }
            }
        }
        VStack {
            Text("O")
                ForEach(numO, id: \.self) { tekst in
                   Button(action: {
                    if self.didTap == false {
                        self.didTap = true
                    } else {
                        self.didTap = false
                    }

                        }) {
                    Text(tekst)
                        .padding()
                        .background(self.didTap ? Color.red : Color.black)
                            .clipShape(Circle())
                }
            }
        }
    }
    }
  }
} 

Upvotes: 0

Views: 798

Answers (1)

Michcio
Michcio

Reputation: 2866

You need to add didTap to every Button. You can simply do it by creating custom view:

struct BingoButton: View {
    var text: String
    @State private var didTap = false

    var body: some View {
        Button(action: {
            self.didTap.toggle()
        }) {
            Text(text)
            .padding()
            .background(didTap ? Color.red : Color.black)
                .clipShape(Circle())
        }
    }
}

And then you can change your implementation to something like this:

        VStack {
            Text("I")
                ForEach(numI, id: \.self) { tekst in
                   BingoButton(text: tekst)
                }
            }
        }


You can consider changing your model and make your UI definition smaller and non-repetitive:

struct BingoRow: Identifiable {
    let id = UUID()
    let headline: String
    let numbers: [String]
}

struct SimpleView: View {
    var rows = [
        BingoRow(headline: "B", numbers: ["5","9","11","15","9"]),
        BingoRow(headline: "I", numbers: ["16","19","21","25","22"]),
        BingoRow(headline: "N", numbers: ["35","39","41","45","42"]),
        BingoRow(headline: "G", numbers: ["55","59","61","57","52"]),
        BingoRow(headline: "O", numbers: ["66","69","71","75","72"])
    ]

    var body: some View {
        HStack {
            ForEach(rows) { row in
                VStack {
                    Text(row.headline)
                    ForEach(row.numbers, id: \.self) { text in
                        BingoButton(text: text)
                    }
                }
            }
        }
    }
}

Upvotes: 2

Related Questions