SwiftUI:在单独的标签中显示滑块位置

SwiftUI: Displaying slider position in a seperate label

这个问题是

的后续问题

基本上我有一个滑块,它是多个滑块之一。每个 on 都会更改模型 class 上的一个参数,因此我传递了一个绑定,该绑定表示模型 class 上的特定 属性。这是因为每次滑块移动时模型都会获得新值。

struct AspectSlider: View {

    private var value: Binding<Double>

    init(value: Binding<Double>, hintKey: String) {
        self.value = value
    }

    var body: some View {
        VStack(alignment: .trailing) {
            Text("\(self.value.value)")
            Slider(value: Binding<Double>(getValue: { self.value.value }, setValue: { self.value.value = [=10=] }),
                    from: 0.0, through: 4.0, by: 0.5)
        }
    }
}

无法正常工作的是 Text("\(self.value.value)") 显示,该显示旨在显示滑块的当前值。当 Binding<Double> 值更改时,它不会更新。

相反,它仅在显示器上的其他内容触发显示刷新时更新。在我的例子中,代表模型执行计算结果的标签(当滑块改变它的值时不一定改变)。

我已确认模型正在发生变化,因此绑定正在更新。我的问题是为什么文本标签没有立即更新。

你的代码,如果这样调用,工作正常:

struct ContentView: View {
    @State private var value: Double = 0

    var body: some View {
        AspectSlider(value: $value, hintKey: "hint")
    }
}

struct AspectSlider: View {

    private var value: Binding<Double>

    init(value: Binding<Double>, hintKey: String) {
        self.value = value
    }

    var body: some View {
        VStack(alignment: .trailing) {
            Text("\(self.value.value)")
            Slider(value: Binding<Double>(getValue: { self.value.value }, setValue: { self.value.value = [=10=] }),
                   from: 0.0, through: 4.0, by: 0.5)
        }
    }
}

请注意,您还可以利用 属性 包装器 @Binding,以避免使用 self.value.value。您的实施应该略有变化:

struct AspectSlider: View {
    @Binding private var value: Double

    init(value: Binding<Double>, hintKey: String) {
        self.$value = value
    }

    var body: some View {
        VStack(alignment: .trailing) {
            Text("\(self.value)")
            Slider(value: Binding<Double>(getValue: { self.value }, setValue: { self.value = [=11=] }),
                   from: 0.0, through: 4.0, by: 0.5)
        }
    }
}

好的,我已经弄清楚为什么我的代码没有按预期更新。它归结为我的模型,看起来像这样(简单版):

final class Calculator: BindableObject {

    let didChange = PassthroughSubject<Int, Never>()
    var total: Int = 0
    var clarity: Double = 0.0 { didSet { calculate() }}

    private func calculate() {
        if newValue.rounded() != Double(total) {
            total = Int(newValue)
            didChange.send(self.total)
        }
    }
}

发生的事情是,sider 上的值仅在该模型执行 didChange.send(self.total) 行时才更新。我认为,如果我做对了,那是因为标签正在监视绑定,只有当绑定更新时标签才会更新。说得通。仍在解决这个问题。

我想这是学习 Combine 及其工作原理的一部分:-)