如何解决使用 SwiftUI 中的数组更新列表中的滑块值文本
应用工作流程是这样的:
到目前为止,一切都很好。每行都有一个滑块,其值存储在数组对象的属性中。但是,移动滑块后不会立即更新值文本,而是会在添加新项目时更新。请看下面的动图:
The Slider doesn't update the text value when moved
如何将滑块运动绑定到文本值?我认为通过定义
@Observedobject var slider_value: SliderVal = SliderVal()
并将该变量绑定到滑块,该值将同时更新,但事实并非如此。非常感谢您的帮助。
import SwiftUI
import Combine
struct ContentView: View {
@Observedobject var db: Db
var body: some View {
NavigationView{
List(db.criteria_db){criteria in
vstack {
HStack{
Text(criteria.name).bold()
Spacer()
Text(String(criteria.slider_value.value)) //<-- Problem here
}
Slider(value: criteria.$slider_value.value,in:0...100,step: 1)
}
}
.navigationBarTitle("Criteria")
.navigationBarItems(trailing:
Button(action: {
Criteria.count += 1
db.criteria_db.append(Criteria(name: "Criteria\(Criteria.count)"))
dump(db.criteria_db)
},label: {
Text("Add Criteria")
})
)
}
.listStyle(InsetGroupedListStyle())
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(db: Db())
}
}
struct Criteria: Identifiable {
var id = UUID()
var name: String
@Observedobject var slider_value: SliderVal = SliderVal()
static var count: Int = 0
init(name: String) {
self.name = name
}
}
class Db: ObservableObject {
@Published var criteria_db: [Criteria] = []
}
class SliderVal: ObservableObject {
@Published var value:Double = 50
}
解决方法
@ObservableObject
在这样的 struct
中不起作用——它只在 SwiftUI View
或 DynamicProperty
中有用。对于您的用例,由于 class
是引用类型,因此 @Published
属性无法知道 SliderVal
已更改,因此所有者 View
永远不会更新.
您可以通过将模型转换为 struct
来解决此问题:
struct Criteria: Identifiable {
var id = UUID()
var name: String
var slider_value: SliderVal = SliderVal()
static var count: Int = 0
init(name: String) {
self.name = name
}
}
struct SliderVal {
var value:Double = 50
}
问题是,一旦您执行此操作,您的 Binding
中就没有可使用的 List
。如果您有幸使用 SwiftUI 3.0(iOS 15 或 macOS 12),您可以在列表中使用 $criteria
来获取当前迭代元素的绑定。
如果您使用的是早期版本,则需要使用索引来迭代项目,或者,我最喜欢的是,创建一个与项目的 id
相关联的自定义绑定。它看起来像这样:
struct ContentView: View {
@ObservedObject var db: Db = Db()
private func bindingForId(id: UUID) -> Binding<Criteria> {
.init {
db.criteria_db.first { $0.id == id } ?? Criteria(name: "")
} set: { newValue in
db.criteria_db = db.criteria_db.map {
$0.id == id ? newValue : $0
}
}
}
var body: some View {
NavigationView{
List(db.criteria_db){criteria in
VStack {
HStack{
Text(criteria.name).bold()
Spacer()
Text(String(criteria.slider_value.value))
}
Slider(value: bindingForId(id: criteria.id).slider_value.value,in:0...100,step: 1)
}
}
.navigationBarTitle("Criteria")
.navigationBarItems(trailing:
Button(action: {
Criteria.count += 1
db.criteria_db.append(Criteria(name: "Criteria\(Criteria.count)"))
dump(db.criteria_db)
},label: {
Text("Add Criteria")
})
)
}
.listStyle(InsetGroupedListStyle())
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(db: Db())
}
}
class Db: ObservableObject {
@Published var criteria_db: [Criteria] = []
}
现在,由于模型都是值类型 (struct
s),View
和 @Published
知道何时更新并且您的滑块按预期工作。
尝试这样的事情:
Sub Loop4Row()
Dim r As Long,Ranges As Range
Set Ranges = Application.InputBox("Select the Range",Type:=8)
For r = Application.Min(Ranges.Column) To Application.Max(Ranges.Columns)
MsgBox Cells(4,r)
Next r
End Sub
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。