Why does answer variable not equal the new value?

I don’t get why it returns 0.0. Why does the multiplication not work?

import Foundation
import SwiftUI

struct CalculateMaintenance{

@State var answer = 0.0
var activityLevel = ""
var bmr = ""


func calculate(activityLevel: String, bmr: String) -> Double {
    
    if (activityLevel == "Little"){
        answer = Double(bmr)! * 1.20
    }
    if (activityLevel == "Low"){
        answer = Double(bmr)! * 1.375
    }
    if (activityLevel == "Moderate"){
        answer = Double(bmr)! * 1.467
    }
    if (activityLevel == "Daily"){
        answer = Double(bmr)! * 1.55
    }
    if (activityLevel == "Active"){
        
        print("----\(Double(bmr)!)")
        answer = Double(bmr)!
        print(">>>>>\(answer)")
        answer = answer * 1.725
        print(answer)
        
    }
    return answer
}

}

this is what i get in the console:

----1915.17

>>>>>0.0

0.0

What value do you expect to get?

Where do you set the values of activityLevel and bmr? You need to set these values and pass them to the calculate function for the multiplication to work.

In the code you showed, both string variables are empty strings. Because the variables are empty strings, the conditions for the if statements are all false. Because the conditions are all false, the calculate function does no multiplication and returns the original value of answer, which is 0.0.

Hi I expect to get 3,303.66. I am passing values.

print(“----(Double(bmr)!)”)

you can see this produces 1915.17

Am I correct in the following statements:

  • activityLevel is "Active"
  • bmr is 1915.17

And you are wondering why the statement

answer = Double(bmr)!

Doesn’t change the value of answer from 0.0 to 1915.17?

And you are wondering why the function returns 0.0 instead of 3303.66?

If all of those statements are correct, there’s nothing in the code you showed that indicates why the answer variable’s value doesn’t change. But you have shown only a small snippet of code, and that makes it more difficult for anyone here to figure out what the problem is.

Why does the answer variable have the @State property wrapper? The @State property wrapper is for variables inside SwiftUI views, and the CalculateMaintenance struct is not a SwiftUI view.

Why are you modifying answer inside the calculate function and returning a value? Your code would be clearer if you created a local variable inside calculate, used that variable to calculate the answer and set the value of answer to the return value of calculate.

answer = calculate("Active", "1915.17")
1 Like

Apologies for the vague answers. Thank you so much for the response.

I have just pushed what i have done so far. GitHub - raitayami/WeightLossMeals

Would you please take a look. It is driving me crazy.

Take a look at this modified version of your code

When passing the bmr value from one view to another it should be done using a Binding in the subsequent views.

I have also created a local variable “answer” in your calculate function to store the value that you return.

Download this version and place somewhere different to that of your current version.

1 Like

Your problem is in ThirdDetailView. Here is the relevant code.

@State var activityLevel = ""

var displayText: Double {
  return CalculateMaintenance().calculate(activityLevel: activityLevel, bmr: bmr)
}

activityLevel is blank. You are passing a blank string to the calculate function instead of an activity level so no multiplication occurs, as I explained in my first response.

Chris_Parker told you the answer, use @Binding for the activity level so you can pass the activity level from the second detail view to the third detail view.

@Binding var activityLevel
1 Like

Just a clarification on the ThirdDetailView in that the bmr is passed as a Binding but the activityLevel is defined as just a var since in the SecondDetailView it is passed as a value rather than from a State variable.

1 Like

Good morning Chris and SwiftDevJournal,

Thank you so much for the assistance. I am reviewing my code and it works. I have a few questions if you don’t mind. I am sorry if the questions i ask cause you to repeat what you may have said.

Why does the SecondDetailView have bmr has @Binding . Before it was @State and in the secondDetailView, if i wrote Text(bmr) it would display the bmr to be whatever that was calculated in the firstDetailView. This allowed me to think that the data was being passed through fine.

Even in the ThirdDetailView I have inserted Text(bmr) and Text(activityLevel) and it seems to display the details fine. Which allowed me to think that the variables had values. Why does making it a @Binding allow the function to work? I feel abit confused.

Shall i remove the @State var answer = 0.0 in the CalculateMaintenance file as it seems redundant.

Again, thank you for all the help you have given me.

I just read this article:

Does this mean when i use @Binding i can use the value that is in it from view to view, however if it is @State i can’t use the value from view to view, just display it?

You’ve got me questioning my own logic which is a good thing. It looks like I have over complicated the issue because in fact in the case of your App you don’t need to declare bmr as a Binding in the subsequent views (Second and Third). You can in fact declare it simply as a var since you are not changing that value, rather you are reading it only. If you were to change that value somewhere in the subsequent views then declaring it as a Binding in those views enables you to change it and have that reflected back in the preceding Views.

I hope I have not lost you yet.

What I did in the example app that you provided was leave the bmr value declared as a State variable in First Detail view and changed them to be simply a var in the Second and Third.

Everything works just fine.

In that article by Paul, what he is doing is changing the Binding value in the AddView which causes the sheet to be dismissed. So in that case the Binding serves as a two way communication.

The updated project:

(same link as previously, just the code has been updated)

1 Like

Oh haha! I don’t know if i am meant to say lol but this is a very lol moment. Am i meant to speak relatively professional here?

Anyways thank you very much for your help Chris! I will play around with it a bit and let you know if i understand it. Appreciate this assistance greatly.

No problem. Glad to help even if it causes me to question myself.

I forgot about answering this question.

Yes, it serves no purpose so you can remove it.