Two Buttons firing in a Form, but not in a VStack - Why?

I've got some code, where I've nested 2 Buttons in an HStack in a Form. When I click either Button, both actions fire, printing "US to Canadian" and" Canadian to US" -- like the HStack itself was receiving the tap.


If I change the Form to a VStack, each Button works separately, as expected.


That's not supposed to happen is it? Is there something about Forms that I'm missing? Or is this a bug?


struct Currency {
    var canadian:String {
        get { "\(canadianDollar)"}
        set { americanDollar = Double(newValue) ?? 0.00}
    }
    var american:String {
        get { "\(americanDollar)"}
        set { americanDollar = Double(newValue) ?? 0.00}
    }
    
    var canadianDollar:Double
    var americanDollar:Double
    
}
struct ContentView : View {
    @State private var currency = Currency(canadianDollar: 0.00, americanDollar: 0.00)
    
    var body: some View {
        NavigationView {
            Form {
                HStack {
                    Text("CAD: ")
                    TextField($currency.canadian).textFieldStyle(.roundedBorder)
                    
                }
                HStack {
                    Text("USD: ")
                    TextField($currency.american).textFieldStyle(.roundedBorder)
                    
                }
                HStack {
                    Button(action: { print("Canadian to US") }){
                        Text("CAD -> USD")
                        }.background(Color.green)
                    Spacer()
                    Button(action: { print("US to Canadian") }){
                        Text("USD -> CAD")
                        }.background(Color.yellow)
                }
                }.navigationBarTitle(Text("Currency Converter"))
        }
        
    }
}

Replies

I'm guessing you intended to write:

var canadian:String { 
        get { "\(canadianDollar)"} 
        set { americanDollar = Double(newValue) ?? 0.00} 
    } 
    var american:String { 
        get { "\(americanDollar)"} 
        set { canadianDollar = Double(newValue) ?? 0.00}


rather than

var canadian:String { 
        get { "\(canadianDollar)"} 
        set { americanDollar = Double(newValue) ?? 0.00} 
    } 
    var american:String { 
        get { "\(americanDollar)"} 
        set { americanDollar = Double(newValue) ?? 0.00}


With that change in place, it performs per stated expectations.

Thanks for your repsonse, m_bedwell, I am grateful. You're right that I have a copy and paste error. I wanted canadianDollar to be a backing variable for canadian, and americanDollar to be a backing variable for american (so I rewrote it as shown below). But regardless of what I do in the getter or setter, when I tap on either Button, both Button's actions get triggered -- e.g., if I tap on CAD ->USD, I see "Canadian to US" and "US to Canadian" being printed. I take it you're seeing something different?


Update (breaking news): if I eliminate the last HStack, or change it to a Group, each button works independently, as it should. It's only in a HStack or VStack that the stack itself seems tappable, and passes the tap to all of its child views.


var canadian:String {
        get { "\(canadianDollar)"}
        set { canadianDollar = Double(newValue) ?? 0.00}
    }
    var american:String {
        get { "\(americanDollar)"}
        set { americanDollar = Double(newValue) ?? 0.00}
    }
    
    var canadianDollar:Double
    var americanDollar:Double

struct ContentView : View {
    @State private var currency = Currency(canadianDollar: 0.00, americanDollar: 0.00)
    
    var body: some View {
        NavigationView {
            Form {
                
                HStack {
                    Text("CAD: ")
                    TextField($currency.canadian).textFieldStyle(.roundedBorder)
                    
                }
                
                HStack {
                    Text("USD: ")
                    TextField($currency.american).textFieldStyle(.roundedBorder)
                    
                }
                HStack {
                    Button(action: { print("Canadian to US") }){
                        Text("CAD -> USD")
                        }.background(Color.green)
                    Button(action: { print("US to Canadian") }){
                        Text("USD -> CAD")
                        }.background(Color.yellow)
                }
                }.navigationBarTitle(Text("Currency Converter"))
        }
        
    }
}