Swift comparison operator in function returning unexpected value

Viewed 29

I'm new to swift and coding in general and am having difficulty with getting the expected result from a comparator operator in a function.

I've made a simplified version of the issue I'm facing. I have multiple buttons and I want to keep track of which one is selected by changing the value of 'count' to the number of that button. I want the background of the buttons to be green when selected to show that they are selected, however, I can't get it to work.

I am using a ternary operator in the '.background()' modifier which calls to a function. The function consistently returns 'false' regardless of what value 'count' is. below the buttons I have written a more verbose way of doing this, which returns the correct bool value.

I can't figure out why the function is not returning the correct value.

struct storedValues {
    var count = 0
}

func checkTapped(_ val: Int) -> Bool {
    @State var values = storedValues()
    
    return values.count == val
}

struct ContentView: View {
    @State private var values = storedValues()
    
    var body: some View {
        VStack {
            // Buttons to change value of count
            HStack{
                Text("Set count to 1")
                    .padding()
                    .onTapGesture {
                        values.count = 1
                    }
                    .background(checkTapped(1) ? .green : .gray)
                Text("Set count to 2")
                    .padding()
                    .onTapGesture {
                        values.count = 2
                    }
                    .background(checkTapped(2) ? .green : .gray)
            }
            
            // Expanded operation meant to be performed by checkTapped, works correctly
            if values.count == 1 {
                Text("Count = 1")
                    .background(.green)
            } else if values.count == 2 {
                Text("Count = 2")
                    .background(.green)
            } else {
                Text("Count != 1,2")
            }
        }
    }
}
1 Answers

You are creating a new storedValues instance inside your checkTapped function instead of comparing to the instance stored on your view.

Instead of doing that, simply declare checkTapped on storedValues and compare the count property against val. This will ensure that you are always checking the state stored on your view rather than creating a new temporary instance incorrectly.

Unrelated to your question, but type names in Swift should be UpperCamelCase, so you should rename storedValues to StoredValues.

struct StoredValues {
  var count = 0

  func checkTapped(_ val: Int) -> Bool {
    count == val
  }
}

struct ContentView: View {
    @State private var values = StoredValues()

    var body: some View {
        VStack {
            // Buttons to change value of count
            HStack{
                Text("Set count to 1")
                    .padding()
                    .onTapGesture {
                        values.count = 1
                    }
                    .background(values.checkTapped(1) ? .green : .gray)
                Text("Set count to 2")
                    .padding()
                    .onTapGesture {
                        values.count = 2
                    }
                    .background(values.checkTapped(2) ? .green : .gray)
            }

            // Expanded operation meant to be performed by checkTapped, works correctly
            if values.count == 1 {
                Text("Count = 1")
                    .background(.green)
            } else if values.count == 2 {
                Text("Count = 2")
                    .background(.green)
            } else {
                Text("Count != 1,2")
            }
        }
    }
}
Related