[英]Bind @State to optional @Binding in the same struct SwiftUI
I am creating a View that may or may not receive a binding:我正在创建一个可能会或可能不会收到绑定的视图:
import SwiftUI
struct AssignmentEditMenu: View {
@EnvironmentObject var planner: Planner
@Environment(\.dismiss) var dismiss
var isEditing // set to true if assignment is not nil
var assignment: Binding<Assignment>?
@State var newAssignment = assignment ?? Assignment()
// if assignment is not nil, create a copy of it and set newAssignment equal to the copy
// if assignment is nil, initialize a new struct and set newAssignment equal to it
var body: some View {
NavigationView {
Form {
nameSection
dateSection
}
.navigationTitle(Text("New Assignment"))
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(isEditing ? "Add" : "Done") {
isEditing ? (assignment = newAssignment) : planner.addAssignment(newAssignment)
dismiss()
}
}
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") {
dismiss()
}
}
}
}
}
var nameSection: some View {
Section {
TextField("Name", text: $newAssignment.name)
Picker("Course", selection: $newAssignment.course) {
ForEach(planner.courses) { course in
Text("\(course.name)").tag(course)
}
}
}
}
var dateSection: some View {
Section {
DatePicker(
selection: $newAssignment.assignedDate,
displayedComponents: [.date, .hourAndMinute]
) {
Text("Assigned:")
.lineLimit(1)
.allowsTightening(true)
}
DatePicker(
selection: $newAssignment.dueDate
) {
Text("Due:")
.lineLimit(1)
.allowsTightening(true)
}
}
}
}
What I am trying to do is if a binding to an Assignment
is passed in here, then the View is in Edit Mode.我想要做的是,如果在此处传递了对Assignment
的绑定,则视图处于编辑模式。 newAssignment
will be set to the same values as the assignment
binding but not reference it at all. newAssignment
将被设置为与assignment
绑定相同的值,但根本不引用它。 It will collect changes and when complete, set that assignment
binding equal to itself, thus saving the changes.它将收集更改并在完成后将assignment
绑定设置为等于自身,从而保存更改。 The reason for using newAssignment
is so that if the user cancels (this view will be a sheet) changes are discarded since newAssignment
is a @State var.使用newAssignment
的原因是,如果用户取消(此视图将是一张工作表)更改将被丢弃,因为newAssignment
是一个 @State 变量。
When no Assignment
binding is passed in the View is in Create mode.当没有传递任何Assignment
绑定时,视图处于创建模式。 newAssignment
collects the changes and is added to the store via planner
. newAssignment
收集更改并通过planner
添加到商店。
Assignment
implementation: Assignment
实现:
struct Assignment: Identifiable, Equatable, Hashable {
var name: String
var assignedDate: Date
var dueDate: Date
var course: Course
var percentCompleted: Double
let id: UUID
init(
name: String = "",
assignedDate: Date = Date(),
dueDate: Date = Calendar.current.nextDate(after: Date(), matching: .init(hour: 0, minute: 0), matchingPolicy: .strict)!,
course: Course = Course()
) {
self.name = name
self.assignedDate = assignedDate
self.dueDate = dueDate
self.course = course
self.id = UUID()
self.percentCompleted = 0.0
}
}
struct Course: Identifiable, Equatable, Hashable {
var name: String
let id: UUID
init(_ name: String = "Course") {
self.name = name
self.id = UUID()
}
}
Add a custom init.添加自定义初始化。 With that, newAssignment
var is also not needed.这样,也不需要newAssignment
var。
struct AssignmentEditMenu: View {
@EnvironmentObject var planner: Planner
@Environment(\.dismiss) var dismiss
var isEditing // set to true if assignment is not nil
var assignment: Binding<Assignment>
init(a: Binding<Assignment> = .constant(Assignment())) {
assignment = a
}
.....
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.