gpt4 book ai didi

swift - 在 SwiftUI 中处理派生状态

转载 作者:行者123 更新时间:2023-12-03 23:27:45 25 4
gpt4 key购买 nike

说我正在创建一个“日期编辑器” View 。目标是:
- 采用默认的种子日期。
- 它允许用户更改输入。
- 如果用户随后选择,他们可以按“保存”,在这种情况下, View 的所有者可以决定对数据进行处理。

这是实现它的一种方法:

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 的用途这里。但我认为你过于依赖事件(一种 UIKit 方式)而不是 单一事实来源原则(SwiftUI 方式)。

更新 :添加了取消日期编辑的方法。
在这种情况下,编辑器 View 应该改变 Binding仅在保存时。为此,它使用私有(private) State将用于日期选择器。这样,事实的来源被保留,因为使用的私有(private)状态永远不会离开编辑 View 的上下文。

struct ContentView: View {
@State var dateEditorVisible = false
@State var date: Date = Date() // source of truth

var body: some View {
NavigationView {
VStack {
Text("\(date.format("HH:mm:ss"))")

Button(action: self.showDateEditor) {
Text("Edit")
}
.sheet(isPresented: $dateEditorVisible) {
// Here we provide a two way binding to the `date` state
// and a way to dismiss the editor view.
DateEditorView(date: self.$date, dismiss: self.hideDateEditor)
}
}
}
}

func showDateEditor() {
dateEditorVisible = true
}

func hideDateEditor() {
dateEditorVisible = false
}
}

struct DateEditorView: View {
// Only a binding.
// Updating this value will update the `@State date` of the parent view
@Binding var date: Date

@State private var editingDate: Date = Date()
private var dismiss: () -> Void

init(date: Binding<Date>, dismiss: @escaping () -> Void) {
self._date = date
self.dismiss = dismiss

// assign the wrapped value as default value for edition
self.editingDate = date.wrappedValue
}

var body: some View {
VStack {
DatePicker(selection: $editingDate, displayedComponents: .hourAndMinute) {
Text("Date")
}

HStack {
Button(action: self.save) {
Text("Save")
}

Button(action: self.dismiss) {
Text("Cancel")
}
}
}
}

func save() {
date = editingDate
dismiss()
}
}

通过这种方式,您无需定义保存操作来更新父 View 或使当前值与某些默认值保持同步。你只有一个单一的事实来源来驱动你的所有 UI。

编辑 :
Date扩展以使其构建。

extension Date {
private static let formater = DateFormatter()

func format(_ format: String) -> String {
Self.formater.dateFormat = format
return Self.formater.string(from: self)
}
}

关于swift - 在 SwiftUI 中处理派生状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59888328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com