SwiftUI help with application of multiple radio buttons to perform calculations based on selected option

I am making this calculator where one option would be selected for each radio button, the question is how to implement code to perform calculation depending on each option. I ma newbie and was able to finally make these multiple radio buttons on screen that grouped together.

For example, if height is in inches, need to first change height to cams, and considering following code, but unable to

`        var heightCms: Double = 0.0

        

        if (heightRadioButtonGroups(callback: heightRadioInchesMajority).isSelected) {

            return Double(height) ?? 1 * 2.54

        } else {

            return Double(height) ?? 1

        } */

Though heightRadioInchesMajority is within the code, but getting error that is out of scope.

Would appreciate a simplified solution. In Android Kotlin, it was easy and was able to do it quickly, but here finding difficult and most of online videos are using Ukit or older versions and not much on swiftUI.

In the code shows I used 1 for default value but doesn't matter if it is 0 or 1. I used 1, so that multiplying with zero results in 0 but with 1 will give same value.

Thank

You do not say what you do depending on the selections.

For instance, if height is cm or inches, I guess you enter some height in a textField and need to convert ?

So, please show the full calculator code, that will be easier to help. In particular, how did you define radio buttons ?

However, you could define computed var, for instance:

I assume you have a way to detect if cm or inch is selected ; and that the value (Double) of the height textField is saved in a var that I call enteredHeight

var  heightInCm: Double {
  if cmSelected { // then user enters cm
    return enteredHeight
   } else {  // then user enters inches
     return enteredHeight * 2.54
  }
}

Thanks, it was long code, here are the details

in the view of all the radio buttons, here is the `//

//  RadioButtons.swift

//  De-Indexed GFR

//

//  Created by Loveleen Parmar on 2021-09-21.

//

import SwiftUI

//MARK:- Single Radio Button Field

struct RadioButtonField: View {

    let id: String

    let label: String

    let size: CGFloat

    let color: Color

    let textSize: CGFloat

    let isMarked:Bool

    let callback: (String)->()

    

    init(

        id: String,

        label:String,

        size: CGFloat = 20,

        color: Color = Color.black,

        textSize: CGFloat = 14,

        isMarked: Bool = false,

        callback: @escaping (String)->()

    ) {

        self.id = id

        self.label = label

        self.size = size

        self.color = color

        self.textSize = textSize

        self.isMarked = isMarked

        self.callback = callback

    }

    

    var body: some View {

        Button(action:{

            self.callback(self.id)

        }) {

            HStack(alignment: .center, spacing: 10) {

                Image(systemName: self.isMarked ? "largecircle.fill.circle" : "circle")

                    .renderingMode(.original)

                    .resizable()

                    .aspectRatio(contentMode: .fit)

                    .frame(width: self.size, height: self.size)

                

                Text(label)

                    //.font(Font.system(size: textSize))

                    .font(.caption)

                

                Spacer()

            }.foregroundColor(self.color)

        }

        .foregroundColor(Color.white)

    }

}

//MARK:- Group of weight Radio Buttons

enum Weight: String {

    case kg = "Kgs"

    case pounds = "lbs"

}

struct weightRadioButtonGroups: View {

    let callback: (String) -> ()

    

    @State var selectedId: String = ""

    

    var body: some View {

        HStack {

            weightRadioKgMajority

            weightRadioPoundsMajority

        }.padding(.leading, 6)

    }

    

    var weightRadioKgMajority: some View {

        RadioButtonField(

            id: Weight.kg.rawValue,

            label: Weight.kg.rawValue,

            isMarked: selectedId == Weight.kg.rawValue ? true : false,

            callback: weightRadioGroupCallback

        )

    }

    

    var weightRadioPoundsMajority: some View {

        RadioButtonField(

            id: Weight.pounds.rawValue,

            label: Weight.pounds.rawValue,

            isMarked: selectedId == Weight.pounds.rawValue ? true : false,

            callback: weightRadioGroupCallback

        )

    }

    

    func weightRadioGroupCallback(id: String) {

        selectedId = id

        callback(id)

    }

}

//MARK:- Group of height Radio Buttons

enum Height: String {

    case cms = "cms"

    case inches = "inches"

}

struct heightRadioButtonGroups: View {

    let callback: (String) -> ()

    

   

    @State var selectedId: String = ""

    

    

    var body: some View {

        HStack {

            heightRadioCmsMajority

            heightRadioInchesMajority

        }.padding(.leading, 8)

    }

    

    var heightRadioCmsMajority: some View {

        RadioButtonField(

            id: Height.cms.rawValue,

            label: Height.cms.rawValue,

            isMarked: selectedId == Height.cms.rawValue ? true : false,

            callback: heightRadioGroupCallback

        )

    }

    

    var heightRadioInchesMajority: some View {

        RadioButtonField(

            id: Height.inches.rawValue,

            label: Height.inches.rawValue,

            isMarked: selectedId == Height.inches.rawValue ? true : false,

            callback: heightRadioGroupCallback

        )

    }

    

    func heightRadioGroupCallback(id: String) {

        selectedId = id

        callback(id)

    }

}

    

//MARK:- Group of creatinine Radio Buttons

enum Creatinine: String {

    case mg = "mg/dL"

    case umol = "\u{03BC}mol/L"

}

struct creatinineRadioButtonGroups: View {

    let callback: (String) -> ()

    

    @State var selectedId: String = ""

    

    var body: some View {

        HStack {

            creatinineRadioMgMajority

            creatinineRadioUmolMajority

        }

    }

    

    var creatinineRadioMgMajority: some View {

        RadioButtonField(

            id: Creatinine.mg.rawValue,

            label: Creatinine.mg.rawValue,

            isMarked: selectedId == Creatinine.mg.rawValue ? true : false,

            callback: creatinineRadioGroupCallback

        )

    }

    

    var creatinineRadioUmolMajority: some View {

        RadioButtonField(

            id: Creatinine.umol.rawValue,

            label: Creatinine.umol.rawValue,

            isMarked: selectedId == Creatinine.umol.rawValue ? true : false,

            callback: creatinineRadioGroupCallback

        )

    }

    

    func creatinineRadioGroupCallback(id: String) {

        selectedId = id

        callback(id)

    }

}

struct RadioButtonFieldView: View {

    var body: some View {

        HStack {

            Text("Sex:")

                .font(Font.headline)

            RadioButtonGroups { selected in

                return

                //print("Selected Sex is: (selected)")

                

            }

        }.padding()

        

        HStack {

            Text("Race:")

                .font(Font.headline)

            raceRadioButtonGroups { selected in

                return

                //print("Selected Race is: (selected)")

            }

        }.padding()

        

        

        HStack {

            Text("Weight:")

                .font(Font.headline)

  

            weightRadioButtonGroups { selected in

                return

                //print("Selected Weight is: (selected)")

            }

        }.padding()

        

        HStack {

            Text("Height:")

                .font(Font.headline)

     

            heightRadioButtonGroups { selected in

                return

               // print("Selected Height is: (selected)")

            }

        }.padding()

        

        HStack {

            Text("Creatinine:")

                .font(Font.headline)

            creatinineRadioButtonGroups { selected in

                return

               // print("Selected Creatinine is: (selected)")

            }

        }.padding()

    }

        

    

}

struct RadioButtonField_Previews: PreviewProvider {

        

 

    

Part 2,

import SwiftUI

struct ContentView: View {

    @State var age = ""

    @State var sex = ""

    @State var race = ""

    @State var height = ""

    @State var weight = ""

    @State var creatinine = ""          var body: some View {

            VStack {

                

                Text("")

                Spacer()

                Group{        

                    HStack {

                        Text("Age (Years):")

                            .fontWeight(/@START_MENU_TOKEN@/.bold/@END_MENU_TOKEN@/)

                            .frame(width: 200, height: 40, alignment: .leading)

                            .padding(.leading, 20)

                        

                        Spacer()

                        

                        TextField("Enter age:", text: $age)

                            .frame(width: 100, height: 40, alignment: .leading)

                            .multilineTextAlignment(.trailing)

                            .padding(.trailing, 20)

                    }

                    HStack {

                        Text("Height:")

                            .fontWeight(/@START_MENU_TOKEN@/.bold/@END_MENU_TOKEN@/)

                            .frame(width: 100, height: 40, alignment: .leading)

                            .padding(.leading, 20)

                        Spacer()

                        heightRadioButtonGroups { selected in

                            return

                         

                        }

                        

                        TextField("Enter Height:", text: $height)

                            .frame(width: 80, height: 40, alignment: .leading)

                            .multilineTextAlignment(.trailing)

                            .padding(.trailing, 20)

                    }

                    HStack {

                        Text("Weight:")

                            .fontWeight(/@START_MENU_TOKEN@/.bold/@END_MENU_TOKEN@/)

                            .frame(width: 100, height: 40, alignment: .leading)

                            .padding(.leading, 20)

                        

                        Spacer()

                        

                        weightRadioButtonGroups { selected in

                            return

                          

                        }

                        

                        TextField("Enter weight", text: $weight)

                            .frame(width: 80, height: 40, alignment: .leading)

                            .multilineTextAlignment(.trailing)

                            .padding(.trailing, 20)

                        

                        

                    }

                    

                Spacer()

                

                Button(action: {

                    

                    //calculate()

                    

                }, label: {

                    Text("CALCULATE")

                        .font(.largeTitle)

                        .fontWeight(.bold)

                        .foregroundColor(Color.white)

                        .background(Color("teal"))

                        .frame(width: 200, height: 40, alignment: /@START_MENU_TOKEN@/.center/@END_MENU_TOKEN@/)

                        .clipShape(RoundedRectangle(cornerRadius: 12))

                        .shadow(radius: 14)

                })

                

               

                    Spacer()

                    

                    Button(action: {

                        

                        // reset()

                        

                    }, label: {

                        Text("RESET")

                            .font(.largeTitle)

                            .fontWeight(.bold)

                            .foregroundColor(Color.white)

                            .background(Color("teal"))

                            .frame(width: 140, height: 40, alignment: /@START_MENU_TOKEN@/.center/@END_MENU_TOKEN@/)

                            .clipShape(RoundedRectangle(cornerRadius: 12))

                            .shadow(radius: 14)

                    })

                    

                }

                

            }

            

        }

        

    }

    

    

   func calculate() -> Double {

    

        var heightCms: Double = 0.0

        

        if (heightRadioButtonGroups(callback: heightRadioInchesMajority).isSelected) {

            return Double(height) ?? 1 * 2.54

        } else {

            return Double(height) ?? 1

        }

This app I made it in Android and available at Google Play store under name "De-Indexed GFR for Drug Dosing" and the link is com.atbeat.de_indexedgfr if you access to android system, you may view it to see what I am trying to do. I am not a programmer but learning and experimenting.

Trying to make something in Swift UI.

Anyone to help with code? Where is the issue in the code and please provide a solution if possible

It is nearly impossible to read code if not formatted.

There are many errors to correct first:

  • line 58: struct name should start with Uppercase.
  • line 182: RadioButtonGroups is undefined. Where is it declared ?
  • line 192, raceRadioButtonGroups is undefined
  • line 233, *** cannot a var name
@State var *** = ""
  • lines 246, 259, 275, 306, 321: what do you mean ? That does not compile.
  • line 328: is it an extra } ? Is calculate inside ContentView ? If outside, several properties are undefined.

Though heightRadioInchesMajority is within the code, but getting error that is out of scope.

heightRadioInchesMajority is a property of heightRadioButtonGroups (better named HeightRadioButtonGroups): it is not directly visible outside.

Is it a code you copied from somewhere ?

Please correct all those errors and then explain what the exact problem is.

Here it is formatted :

Thanks. The code was too long and wouldn't fit in one window, I deleted Race code to fit, and was similar in pattern. The RadioButtonGroups is first declared under Sex RadioButtonGroups, and for the remainder buttons, I added the Height, Weight, Race etc in front to assure each Button being unique.

Yes, I used, the video presented at this link https://thinkdiff.net/how-to-create-radio-button-and-group-in-swiftui-46b34e0ba69a to make radio Buttons and changed the names to fit. Here the author did use "@State var selectedId: String = "" ", so I used the same.

I have capitalized the first letter of struct where I missed.

for each button have to access the property, so if I know how to access for one button then can use the same code for others. So how to access this "HeightRadioInchesMajority" for "Height" buttons. Yes there is a textfield where the value is entered, and then one of the two buttons ('"Cms" or "inches") is clicked by the person entering the value. IN order to do calculations, need to convert values to one unit (metric) and then perform calculations.

The question is how to access this property, as I am at present trying to do and learn for one of the buttons, first.

I have code in two swiftUI files at present,

  1. ContentView
  2. RadioButtons

What you want in fact is share properties between different Views. Environment object are a way to do this.

h t t p s : / / w w w.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views

OK Will try. Thanks

SwiftUI help with application of multiple radio buttons to perform calculations based on selected option
 
 
Q