使用对象收集表单数据并在 Swift 中设置默认值
Use an object to collect form data and set default value in Swift
我是 Swift 开发的新手,我一辈子都弄不明白。我想做的就是使用一个对象来收集表单数据,将其保存到 Realm,然后通过 API.
将其发送到服务器
在我发现的每个示例中,人们都在为其表单中的每个元素创建一个新的 State 变量。这对于具有许多字段的表单来说似乎不切实际,因此我尝试只创建一个具有与我需要的表单字段匹配的属性的对象。如果我不尝试设置任何默认值,这将按我的预期工作。但是,当我尝试为 init()
中的表单设置一些默认值时,出现了我不知道如何解决的错误。这是部分代码:
将用于收集表单数据的对象:
class RecordObject: ObservableObject {
var routeId: Int?
var typeId: Int?
var inDate: Date?
var outDate: Date?
var nextDate: Date?
// .... more properties
}
我想做的是在视图中,在 init()
中设置一些默认值,需要一些逻辑来导出值:
在视图中:
struct AddLauncherView: View {
var route: Route // this is passed from a previous view that lists all the routes
@StateObject var record: RecordObject = RecordObject() // this is where I want to store all the form data
init(){
_record.routeId = self.route.id // I get the error: Referencing property 'routeId' requires wrapped value of type 'RecordObject'
self.record.inDate = Date() // this gives the error: 'self' used before all stored properties are initialized
//self.record.nextDate = here I need to do some date math to figure out the next date
}
var body: some View {
Form{
DatePicker("In Date", selection: $record.inDate, displayedComponents: .date)
// .... more form elements
}
}
}
我知道我可以在 RecordObject
class 中添加默认值,但是有些属性需要一些逻辑来分配默认值。
有人可以帮助 Swift 菜鸟并给我一些指导来完成这项工作吗?我真的需要为视图中的每个表单字段创建一个状态变量吗?
您使用的 ObservableObject
不正确。您的数据模型应该是一个结构,然后 class 发布结构类型的值,因此:
struct Record: Identifiable {
// First, save yourself some grief later and make it conform to Identifiable
let id = UUID()
// The listed variables are probably non-optional in your data model.
// If they are optional, mark them as optional, otherwise
var routeId: Int
var typeId: Int
var inDate: Date
// These are more likely optional
var outDate: Date?
var nextDate: Date?
// .... more properties
}
class RecordObject: ObservableObject {
// Make the source of truth @Published so things are updated in your view
@Published var records: [Record] = []
// OR use an init
@Published var records: [Record]
init(records: [Records] {
self.records = records
// or call some function that imports/creates the records...
}
}
如果您确实使用了 class
(ObservableObject
),您会希望使用 @Published
对属性进行注释。但是,使用 struct
和包含您需要的所有各种属性的 @State
变量可能是更好的主意。这可能看起来像这样:
struct Record {
var routeId: Int?
var typeId: Int?
var inDate: Date?
var outDate: Date?
var nextDate: Date?
}
struct AddLauncherView: View {
var route: Route
@State var record: Record
init(route: Route) {
self.route = route
_record = State(initialValue: Record(routeId: route.id,
typeId: nil,
inDate: Date(),
outDate: nil,
nextDate: nil))
}
var body: some View {
Form{
DatePicker("In Date",
selection: Binding<Date>(get: {record.inDate ?? Date()},
//custom binding only necessary if inDate is Date? -- if you make it just Date, you can bind directly to $record.inDate
set: {record.inDate = [=10=]}),
displayedComponents: .date)
// .... more form elements
}
}
}
我是 Swift 开发的新手,我一辈子都弄不明白。我想做的就是使用一个对象来收集表单数据,将其保存到 Realm,然后通过 API.
将其发送到服务器在我发现的每个示例中,人们都在为其表单中的每个元素创建一个新的 State 变量。这对于具有许多字段的表单来说似乎不切实际,因此我尝试只创建一个具有与我需要的表单字段匹配的属性的对象。如果我不尝试设置任何默认值,这将按我的预期工作。但是,当我尝试为 init()
中的表单设置一些默认值时,出现了我不知道如何解决的错误。这是部分代码:
将用于收集表单数据的对象:
class RecordObject: ObservableObject {
var routeId: Int?
var typeId: Int?
var inDate: Date?
var outDate: Date?
var nextDate: Date?
// .... more properties
}
我想做的是在视图中,在 init()
中设置一些默认值,需要一些逻辑来导出值:
在视图中:
struct AddLauncherView: View {
var route: Route // this is passed from a previous view that lists all the routes
@StateObject var record: RecordObject = RecordObject() // this is where I want to store all the form data
init(){
_record.routeId = self.route.id // I get the error: Referencing property 'routeId' requires wrapped value of type 'RecordObject'
self.record.inDate = Date() // this gives the error: 'self' used before all stored properties are initialized
//self.record.nextDate = here I need to do some date math to figure out the next date
}
var body: some View {
Form{
DatePicker("In Date", selection: $record.inDate, displayedComponents: .date)
// .... more form elements
}
}
}
我知道我可以在 RecordObject
class 中添加默认值,但是有些属性需要一些逻辑来分配默认值。
有人可以帮助 Swift 菜鸟并给我一些指导来完成这项工作吗?我真的需要为视图中的每个表单字段创建一个状态变量吗?
您使用的 ObservableObject
不正确。您的数据模型应该是一个结构,然后 class 发布结构类型的值,因此:
struct Record: Identifiable {
// First, save yourself some grief later and make it conform to Identifiable
let id = UUID()
// The listed variables are probably non-optional in your data model.
// If they are optional, mark them as optional, otherwise
var routeId: Int
var typeId: Int
var inDate: Date
// These are more likely optional
var outDate: Date?
var nextDate: Date?
// .... more properties
}
class RecordObject: ObservableObject {
// Make the source of truth @Published so things are updated in your view
@Published var records: [Record] = []
// OR use an init
@Published var records: [Record]
init(records: [Records] {
self.records = records
// or call some function that imports/creates the records...
}
}
如果您确实使用了 class
(ObservableObject
),您会希望使用 @Published
对属性进行注释。但是,使用 struct
和包含您需要的所有各种属性的 @State
变量可能是更好的主意。这可能看起来像这样:
struct Record {
var routeId: Int?
var typeId: Int?
var inDate: Date?
var outDate: Date?
var nextDate: Date?
}
struct AddLauncherView: View {
var route: Route
@State var record: Record
init(route: Route) {
self.route = route
_record = State(initialValue: Record(routeId: route.id,
typeId: nil,
inDate: Date(),
outDate: nil,
nextDate: nil))
}
var body: some View {
Form{
DatePicker("In Date",
selection: Binding<Date>(get: {record.inDate ?? Date()},
//custom binding only necessary if inDate is Date? -- if you make it just Date, you can bind directly to $record.inDate
set: {record.inDate = [=10=]}),
displayedComponents: .date)
// .... more form elements
}
}
}