如何从计算属性更新ObservableObject属性?

时间:2020-05-03 21:11:28

标签: swift swiftui

是否可以通过计算属性来更新ObservableObject属性?

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
  ...
}

我知道我可以做到:

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

但是理想情况下,我有一个用例可以让我拥有一个局部变量。除非有解决此问题的方法,否则我发现Text(...)中的prop1不会在更改时进行更新。

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)
        }
    }
}

因为我需要在属性之前使用@Published关键字,以便可以将其更改存储并发布给订阅者,但是问题是我无法控制“ SomeInstance”,因此从外部库中获取。

1 个答案:

答案 0 :(得分:1)

您可以在滑块内使用自定义绑定来更新值。在这里,我制作了带有自定义绑定的Slider View。

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
}