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 及其工作原理的一部分:-)
这个问题是
基本上我有一个滑块,它是多个滑块之一。每个 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 及其工作原理的一部分:-)