假设我正在创建一个“日期编辑器”视图。目标是:
- 采用默认的种子日期。
- 它允许用户更改输入。
- 如果用户随后选择,他们可以按“保存”,在这种情况下,视图的所有者可以决定对数据执行某些操作。
这是实现它的一种方法:
struct AlarmEditor : View {
var seedDate : Date
var handleSave : (Date) -> Void
@State var editingDate : Date?
var body : some View {
let dateBinding : Binding<Date> = Binding(
get: {
return self.editingDate ?? seedDate
},
set: { date in
self.editingDate = date
}
)
return VStack {
DatePicker(
selection: dateBinding,
displayedComponents: .hourAndMinute,
label: { Text("Date") }
)
Spacer()
Button(action: {
self.handleSave(dateBinding.wrappedValue)
}) {
Text("Save").font(.headline).bold()
}
}
}
}
问题
如果所有者改变了值怎么办seedDate
?
在这种情况下,我想做的是重置editingDate
到新的seedDate。
这样做的惯用方法是什么?
我更愿意通过此类编辑器显式使用 ViewModel 来完成此操作,并且它需要对代码进行最少的修改。这是可能的方法(使用 Xcode 11.2.1 进行测试和使用):
测试家长
struct TestAlarmEditor: View {
private var editorModel = AlarmEditorViewModel()
var body: some View {
VStack {
AlarmEditor(viewModel: self.editorModel, handleSave: {_ in }, editingDate: nil)
Button("Reset") {
self.editorModel.seedDate = Date(timeIntervalSinceNow: 60 * 60)
}
}
}
}
编辑器的简单视图模型
class AlarmEditorViewModel: ObservableObject {
@Published var seedDate = Date() // << can be any or set via init
}
更新了编辑器
struct AlarmEditor : View {
@ObservedObject var viewModel : AlarmEditorViewModel
var handleSave : (Date) -> Void
@State var editingDate : Date?
var body : some View {
let dateBinding : Binding<Date> = Binding(
get: {
return self.editingDate ?? self.viewModel.seedDate
},
set: { date in
self.editingDate = date
}
)
return VStack {
DatePicker(
selection: dateBinding,
displayedComponents: .hourAndMinute,
label: { Text("Date") }
)
.onReceive(self.viewModel.$seedDate, perform: {
self.editingDate = $0 }) // << reset here
Spacer()
Button(action: {
self.handleSave(dateBinding.wrappedValue)
}) {
Text("Save").font(.headline).bold()
}
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)