简体   繁体   中英

How to update an ObservableObject property from a computed property?

Is it doable to update an ObservableObject property from a computed property?

struct ContentView: View {
    @EnvironmentObject var foobar: Foobar
    @State var localProp1: Double = 0 {
        didSet {
            self.foobar.someInstance.prop1 = self.localProp1
        }
    }

    var body: some View {
        VStack {
            Text("localProp1 is \(String(format: "%.2f", self.localProp1))")
            Slider(value: self.$localProp1, in: 60...120, step: 1)
        }
    }
}

class Foobar: ObservableObject {
  var someInstance: SomeInstance = SomeInstance()
}

class SomeInstance {
  var prop1: Double
  ...
}

I understand I can:

        Slider(value: self.$foobar.someInstance.prop1, in: 60...120, step: 1)

But the use case I have ideally would let me have a local variable. Unless there's a way around the issue I find where the prop1 in Text(...) is not updated on change.

struct ContentView: View {
    @EnvironmentObject var foobar: Foobar

    var body: some View {
        VStack {
            Text("localProp1 is \(String(format: "%.2f", self.foobar.someInstance.prop1))")
            Slider(value: self.$foobar.someInstance.prop1, in: 60...120, step: 1)
        }
    }
}

Because I'd need to use the @Published keyword before the property so that can store and publish their changes to the subscribers, but the problem is that I don't have control over the "SomeInstance", I'm consuming it from an external library.

You can use custom binding inside slider to update the value. Here I made a Slider View with custom binding.

import SwiftUI

struct TestView: View {
    @EnvironmentObject var foobar: Foobar
    var body: some View {
        VStack {
            Text("localProp1 is \(String(format: "%.2f", self.foobar.someInstance.prop1))")
            MySlider()
        }
    }
}

struct MySlider: View {
    @EnvironmentObject var foobar: Foobar
    var body: some View {
        Slider(value: Binding<Double>(
            get: { () -> Double in
                return self.foobar.someInstance.prop1
        }) { (val) in
            let inst = self.foobar.someInstance
            inst.prop1 = val
            self.foobar.someInstance = inst
        }, in: 60...120, step: 1)
    }
}

class Foobar: ObservableObject {
    @Published var someInstance: SomeInstance = SomeInstance()
}

class SomeInstance {
    var prop1: Double = 70.0
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM