Learn Courses My Dashboard

@State Initializers not working

Hello, I come across a problem I cannot solve, also the stack overflow results don’t show the solution. I also searched this forum.
I have to Integer variables which are in a Textfield and want to make a mathematic addition and present it as a variable in a Text. But the Initialization does not work correctly
That’s what I want to achieve
var var1 = 1
var var2 = 2
var result = (var1 * 75) + (var2 * 85)

That’s my solution but it does not work unfortunately

Thanks for reading

import SwiftUI

class Crew {
var var1:Int = 1
var var2:Int = 2
var result:Int = (var1 * 75) + (var2 *85)

init(var1: Int, var2: Int, result: Int) {
    _var1 = State(initialValue: 1)
    _var2 = State(initialValue: 2)
    _result = State(initialValue: 3)
}

}

 struct DOWView: View {
    
   @State var crew = Crew()
    
    
var body: some View {
    
    VStack {
        TextField("#", value: $crew.var1, format: .number)
        TextField("#", value: $crew.var2, format: .number)
        Text("\(crew.result)")
        
        
    }
    
    struct DOWView_Previews: PreviewProvider {
        static var previews: some View {
            DOWView()
        }
    }

Got it to work doing this. Not sure how set you are in using a class to achieve this.

struct ContentView: View {
    @State var var1: Int = 1
     @State var var2: Int = 2
    var body: some View {
        @State var result = (var1 * 75) + (var2 * 75)
        VStack {
                TextField("#", value: $var1, formatter: NumberFormatter())
                    .padding()
                
                TextField("#", value: $var2, formatter: NumberFormatter())
                    .padding()
                
                Text("Result: \(result)")
                    .padding()
                
                Spacer()
            }
            .padding()
        }
    }

The Crew class should conform to ObservableObject and your variables should then be Published properties instead

unfortunately this did not work.

Hi mika, could you please show this to me in a code. I am confused right now, because I tried so many variants.

I think I got the “blueprint” right, but something is missing…

class Crew: ObservableObject {
@Published var var1:Int = 1
@Published var var2:Int = 1
@Published var result:Int = (var1 * 75) + (var2 * 85)

init(var1: Int, var2: Int, result: Int) {
  let  var1 = State(initialValue: 1)
  let  var2 = State(initialValue: 2)
  let  result = State(initialValue: 3)
}
}

struct DOWView: View {

@ObservedObject var crew = Crew(var1: Int, var2: Int, result: Int)

var body: some View {

HStack {
TextField("#", value: $crew.var1, formatter: NumberFormatter())
TextField("#", value: $crew.var2, formatter: NumberFormatter())
Text(“Result: (crew.result)”)
}

}

}

struct DOWView_Previews: PreviewProvider {

static var previews: some View {

DOWView()

}

}

You don’t need an initializer in your class. Also see you’re mismatching them, labeling them as Published but then initializing it as State.

You’re also passing this incorrectly in DOWView you should be passing real values, not Int

It’ll look very similar to this except using the wrappers I mentioned.

I’ll try to post a sample later when I have time

1 Like

“I’ll try to post a sample later when I have time”

This would be great. Thanks.

In the mean time, you should look at how State, Binding, ObservableObject property wrappers work

1 Like

After looking at this more closely there’s several reasons why it wasn’t working:

  • Like I originally said, at first, you need to use the Published property wrapper
  • I changed result to be a computed property, because if you’re only going to use it as a “result” for something, and not actually have the user do anything with, it’s better for it to be computed
  • changing the initializer to not use State because you don’t need to
  • Also removed result from the initializer because I changed it to a computed property
  • Inside DOWView it should actually be using StateObject
  • For showing the result, you’re trying to use string interpolation, but you had the syntax wrong, it looks like: "whatever string you want \(variableName) more random words"

Here’s the code sample:

class Crew: ObservableObject {
    @Published var var1:Int = 0
    @Published var var2:Int = 0
    var result:Int {
        (var1 * 75) + (var2 * 85)
    }
    
    init(var1: Int, var2: Int) {
        self.var1 = var1
        self.var2 = var2
    }
}

struct DOWView: View {
    
    @StateObject var crew = Crew(var1: 1, var2: 2)
    
    var body: some View {
        HStack {
            TextField("#", value: $crew.var1, formatter: NumberFormatter())
            TextField("#", value: $crew.var2, formatter: NumberFormatter())
            Text("Result: \(crew.result)")
        }
    }
}
1 Like

Thank you for your solution. It works just perfect

1 Like

Hi, once again:

with this solution I guess it is not possible to pass the result variable (crew.result) in to another View ? Am I correct ? It gets stuck in this single View

class Crew: ObservableObject {
@Published var var1:Int = 0
@Published var var2:Int = 0
var result:Int {
(var1 * 75) + (var2 * 85)
}

No you can pass it into another view.

What does your code look like?

Class:

class DowWeights: ObservableObject {
let basicweight:Int = 35000
@Published var cockpit:Int = 0
@Published var cabin:Int = 0
var crew:Int { Int((cockpit * 85) + (cabin * 75)) }

var result:Int { basicweight + crew + pantry } 
//wanted to rewrite this variable to @Published but it does not work

init(pantry:Int, cockpit: Int, cabin: Int) {
    self.cockpit = cockpit
    self.cabin = cabin
}

}

ParentView with Textfield:

struct DOWView: View {

@ObservedObject var dowweights = DowWeights(cockpit: 1, cabin: 1, potwater: 5)

var body: some View {

VStack {
Text("(dowweights.basicweight)")
TextField("#", value: $dowweights.cockpit, formatter: NumberFormatter())
TextField("#", value: $dowweights.cabin, formatter: NumberFormatter())
Text("(dowweights.result)") //Result of all together

}

ChildView:

struct FuelView: View {

@ObservedObject var resultcall = DowWeights( cockpit: 0, cabin: 0)

var body: some View {

            Text("\resultcall.result)")
}

}

Rewrite the variable result to @Published does not work.
I am making an instance in my FuelView of the class DowWeights with the ObservedObject but the changes in resultcall.result don’t change when I type something in the Textfield of the ParentView (DOWView) and don’t update. I think because it is not stored somewhere. Maybe I have to use UserDefaults to save it somewhere ?