mallow
mallow

Reputation: 2836

SwiftUI - Add values from two textfields using var or let

How to add values of two textfields in SwiftUI?

I have this code:

import SwiftUI

struct ContentView: View {
    
    @State private var value1 = ""
    @State private var value2 = ""
    
    private var sumValues = (Int(value1) ?? 0) + (Int(value2) ?? 0)
    
    var body: some View {
        VStack {
            TextField("type value 1 here", text: $value1)
                .keyboardType(.numberPad)
            
            TextField("type value 2 here", text: $value2)
                .keyboardType(.numberPad)
            
            Text("sum: \(sumValues)")
            
            // I need to have a var or let, so I cannot use something like this:
            //Text("sum: \((Int(value1) ?? 0) + (Int(value2) ?? 0))")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I am getting this error on line with private var sumValues...:

Cannot use instance member 'value1' within property initializer; property initializers run before 'self' is available

Cannot use instance member 'value2' within property initializer; property initializers run before 'self' is available

Upvotes: 2

Views: 1857

Answers (3)

Asperi
Asperi

Reputation: 257533

The possible approach is to move all this logic (and might be all other) into view model, like below - so keep engine separated of view and let standard observed dynamic property take care of view updates:

Here is simple demo. Tested with Xcode 12 / iOS 14

class CalcViewModel: ObservableObject {
    @Published var value1 = "" {
        didSet { update() }
    }
    @Published var value2 = "" {
        didSet { update() }
    }
    @Published var sum: Int = 0

    private func update() {
        self.sum = (Int(value1) ?? 0) + (Int(value2) ?? 0)
    }
}

struct ContentView: View {
    @ObservedObject var vm = CalcViewModel()

    var body: some View {
        VStack {
            TextField("type value 1 here", text: $vm.value1)
                .keyboardType(.numberPad)

            TextField("type value 2 here", text: $vm.value2)
                .keyboardType(.numberPad)

            Text("sum: \(vm.sum)")
        }
    }
}

Upvotes: 2

Frankenstein
Frankenstein

Reputation: 16341

Use a computed-property.

private var sumValues: Int { (Int(value1) ?? 0) + (Int(value2) ?? 0) }

Upvotes: 3

finebel
finebel

Reputation: 2355

I think you can change sumValues to a computed property:

private var sumValues: Int {
        get {
            (Int(value1) ?? 0) + (Int(value2) ?? 0)
        }
}

Upvotes: 0

Related Questions