3

I am currently building a small one view app to help learn some more SwiftUI. The app is a simple app to calculate values in a ratio. I have 4 main variables at the moment, the left and right side of the ratio, and the first and second value that will be calculated in ratio. Initially I had each of these stored as @State properties:

@State var leftSide = Double()
@State var rightSide = Double()
@State var value1 = Double()
@State var value2 = Double()

In the app there are 4 sliders that allow each variable to be changed independently of each other. What I want to now allow to happen is that changing the variable value1 will also update value2 according to the ratio the user has set. To achieve this I believe I need to use Combine however I have not got much experience with the framework.

To begin with I moved the variables to an ObservableObject class:

final class UserData: ObservableObject {
    @Published var leftSide = Double()
    @Published var rightSide = Double()
    @Published var value1 = Double()
    @Published var value2 = Double()
}

I updated my main view with @ObservedObject var userData = UserData() so I could access the variables in my view and this works fine

Now I want to update the value1 and value2 variables when the other changes. From the reading I have done I think I need to use a subscriber but I cannot find anything on how to set this up with they @Published property. Have I gone about this in the correct way or is there a better way to do this?

1
  • I am looking into using didSet and i think this will work Commented Feb 26, 2020 at 23:27

1 Answer 1

2

I have 4 main variables at the moment, the left and right side of the ratio, and the first and second value that will be calculated in ratio

so, why you don't declare it as computed variables?

final class UserData: ObservableObject {
    @Published var leftSide = 0.0
    @Published var rightSide = 0.0
    var value: Double {
        // perform the calculation here
        ...
    }
}

If you like to change value independently (bind it to SwiftUI component), and modify the value in case leftSide or rightSide are modified, use willSet or even didSet

final class UserData: ObservableObject {
    @Published var leftSide = 0.0 {
        willSet {
           // update value 
            value = f(newValue)
        }
        didSet {
           // update value
           value = f(oldValue)
        }
    }
    @Published var rightSide = 0.0
    @Published var value = 0.0
    func f(_ v: Double)->Double {
        ......
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I think this suggestion is right on - using Combine to compute the values is doable, but probably way more overhead than you actually want or need. If you wanted to do something like that, you can see an example of how that might work in some of the example code from Using Combine: github.com/heckj/swiftui-notes/blob/master/SwiftUI-Notes/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.