I am creating a scorekeeper for board games. I have created numbered buttons that are supposed to increment my score by the number on the buttons. However, when the buttons are pressed no action occurs. When I set up a break point I can tell the button is being called, but no action is occurring - even when I put in basic elements such as changing my player name. Can you help me get the button to increment the "score" by the number displayed on the button.
struct ContentView: View {
@EnvironmentObject var theGame:Game
@ObservedObject var player1: Player
@ObservedObject var player2: Player
@ObservedObject var player3: Player
@ObservedObject var player4: Player
@State var isPlayer1Active: Bool = false
@State var isPlayer2Active: Bool = false
@State var isPlayer3Active: Bool = false
@State var isPlayer4Active: Bool = false
var body: some View {
VStack {
AdBannerView()
HStack{
VStack{
Spacer()
HStack{
VStack{
Button(action:{
player1.isPlayerActive = true
player2.isPlayerActive = false
player3.isPlayerActive = false
player4.isPlayerActive = false
theGame.activePlayer = player1.playerName
}){
PlayerView(player: player1)
}
Button(action:{
player1.isPlayerActive = false
player2.isPlayerActive = true
player3.isPlayerActive = false
player4.isPlayerActive = false
theGame.activePlayer = player2.playerName
}){
PlayerView(player: player2)
}
}
VStack{
Button(action:{
player1.isPlayerActive = false
player2.isPlayerActive = false
player3.isPlayerActive = true
player4.isPlayerActive = false
theGame.activePlayer = player3.playerName
}){
PlayerView(player: player3)
}
Button(action:{
player1.isPlayerActive = false
player2.isPlayerActive = false
player3.isPlayerActive = false
player4.isPlayerActive = true
theGame.activePlayer = player4.playerName
}){
PlayerView(player: player4)
}
}
addPointsCombinedView(player1: Player(), player2: Player(),player3: Player(), player4: Player())
.padding()
.layoutPriority(1)
}
.padding()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(player1: Player(), player2: Player(),player3: Player(), player4: Player())
.environmentObject(Game(numberOfPlayers: 4))
.previewDevice("iPad Pro (9.7-inch)")
}
}
PlayerView
struct PlayerView: View {
@ObservedObject var player: Player
@EnvironmentObject var theGame:Game;
@State var changeName: Bool = false
var borderSize: CGFloat = 2
var body: some View {
HStack{
Text(player.playerName)
.foregroundColor(.white)
.padding()
VStack{
Text("Score")
Text(player.formattedScore)
}
.foregroundColor(.white)
.padding()
}
.background(player.isPlayerActive ? Color.blue : Color.green)
.cornerRadius(25)
}
}
/* Extension that allows custom corner radius for each corner. This code was created by Mojtaba Hosseini and found on StackOverflow https://stackoverflow.com/questions/56760335/round-specific-corners-swiftui*/
/* extension View {
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
clipShape(playerRoundedCornerView(radius: radius, corners: corners) )
}
}*/
/*This code was created by Mojtaba Hosseini and found on StackOverflow https://stackoverflow.com/questions/56760335/round-specific-corners-swiftui*/
struct playerRoundedCornerView: Shape {
var radius: CGFloat = .infinity
var corners: UIRectCorner = .allCorners
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
struct PlayerView_Previews: PreviewProvider {
static var previews: some View {
PlayerView(player: Player())
}
}
AddScore Button
struct addScoreButton: View {
@ObservedObject var player1: Player
@ObservedObject var player2: Player
@ObservedObject var player3: Player
@ObservedObject var player4: Player
@EnvironmentObject var theGame:Game
var numberToAdd:String
var body: some View {
Button(action: {
player1.changePlayerName(newPlayerName: "Hello2")
switch theGame.activePlayer{
case player1.playerName:
player1.addToScore(pointToAdd: addScore(numberToAdd: numberToAdd))
case player2.playerName:
player2.addToScore(pointToAdd: addScore(numberToAdd: numberToAdd))
default:
theGame.activePlayer = "hello world"
}}){
ZStack{
Rectangle()
.fill(Color.gray)
//.frame(width: 75, height: 75, alignment: .center)
.frame(minWidth: 70, idealWidth: 75, maxWidth: 100, minHeight: 70, idealHeight: 75, maxHeight: 100, alignment: .center)
.padding(.bottom, 5)
Text("\(numberToAdd)")
.foregroundColor(.white)
.bold()
.font(.title)
}
}
}
}
struct addScoreButton_Previews: PreviewProvider {
static var previews: some View {
addScoreButton(player1: Player(), player2: Player(),player3: Player(), player4: Player(),numberToAdd: "+1")
}
}
func addScore(numberToAdd:String) -> Int {
switch numberToAdd {
case "+1":
return 1
case "+2":
return 2
case "+3":
return 3
case "+4":
return 4
case "+5":
return 5
case "+6":
return 6
case "+12":
return 12
case "-1":
return -1
case "-2":
return -2
default:
return -3
}
}
Combined View of the buttons:
struct addPointsCombinedView: View {
@ObservedObject var player1: Player
@ObservedObject var player2: Player
@ObservedObject var player3: Player
@ObservedObject var player4: Player
@EnvironmentObject var theGame:Game
var one:String = "+1"
var two:String = "+2"
var three:String = "+3"
var four:String = "+4"
var five:String = "+5"
var six:String = "+6"
var twelve:String = "+12"
var negOne:String = "-1"
var negTwo:String = "-2"
var body: some View {
HStack {
VStack{
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4, numberToAdd: one)
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: four)
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: twelve)
}
.padding(.trailing, 3)
VStack{
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: two)
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: five)
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: negOne)
}
VStack{
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: three)
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: six)
addScoreButton(player1: player1, player2: player2,player3: player3, player4: player4,numberToAdd: negTwo)
}
.padding(.leading, 3)
}
}
}
struct addPointsCombinedView_Previews: PreviewProvider {
static var previews: some View {
addPointsCombinedView(player1: Player(), player2: Player(),player3: Player(), player4: Player())
}
}
PlayerObject:
class Player:ObservableObject {
@Published var playerName:String
@Published var score:[GameRound] = []
@Published var isPlayerPlayingThisGame:Bool
@Published var isPlayerActive:Bool
@Published var currentScore: Int
var formattedScore:String{
String(currentScore)
}
//@Published let currentRound:Int
//@Published var beginningScore:Int
//@Published var endScore:Int
//@Published var pointsThisRound:[Int]
init(){
playerName = "Player1"
let newGame = GameRound(newRound: 1,beginningScore: 0 )
isPlayerActive = false
isPlayerPlayingThisGame = false
currentScore = 0
score.append(newGame)
}
func changePlayerName(newPlayerName: String){
playerName = newPlayerName
}
/*adds the new points to the array of points made this round
and adds them to the current score */
func addToScore(pointToAdd: Int){
//score.last?.addScore(pointsToAdd: pointToAdd)
self.currentScore += pointToAdd
score.last?.endScore += pointToAdd
score.last?.pointsThisRound.append(pointToAdd)
}
/*starts a new round of the game*/
func newRound(){
let newRound = GameRound(newRound:self.score.last!.currentRound+1,beginningScore: self.score.last!.endScore)
self.score.append(newRound)
}
}
GameRoundObject
class GameRound{
let currentRound:Int
var beginningScore:Int
var endScore:Int
var pointsThisRound:[Int]
var scoreAsString:String{String(endScore)}
init(newRound:Int, beginningScore: Int){
self.currentRound = newRound
self.beginningScore = beginningScore
self.endScore = newRound
self.pointsThisRound = [0]
}
func addScore(pointsToAdd:Int){
self.endScore += pointsToAdd
self.pointsThisRound.append(pointsToAdd)
}
func roundAsString()->String{
var roundNumber:String
var round = "Round:"
roundNumber = "\(self.currentRound)"
round += roundNumber
return round
}
}
Game Object
class Game:ObservableObject{
@Published var player1 = Player()
@Published var player2 = Player()
@Published var player3 = Player()
@Published var player4 = Player()
@Published var activePlayer:String
@Published var game:[Player] = []
@Published var currerntRound: Int
init(numberOfPlayers: Int){
activePlayer = " "
currerntRound = 1
for i in 1...numberOfPlayers{
switch i {
case 1:
game.append(player1)
player1.isPlayerPlayingThisGame = true
case 2:
game.append(player2)
player2.isPlayerPlayingThisGame = true
case 3:
game.append(player3)
player3.isPlayerPlayingThisGame = true
case 4:
game.append(player4)
player4.isPlayerPlayingThisGame = true
default:
break
}
}
}
}