假设我正在创建一个“日期编辑器”视图。目标是: - 采用默认的种子日期。- 它允许用户更改输入。- 如果用户随后选择,他们可以按“保存”,在这种情况下,视图的所有者可以决定对数据执行某些操作。
这是实现它的一种方法:
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()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题
如果所有者改变 的值怎么办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)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑器的简单视图模型
class AlarmEditorViewModel: ObservableObject {
@Published var seedDate = Date() // << can be any or set via init
}
Run Code Online (Sandbox Code Playgroud)
更新了编辑器
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()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1970 次 |
| 最近记录: |