在同一结构 SwiftUI 中将 @State 绑定到可选的 @Binding
Bind @State to optional @Binding in the same struct SwiftUI
我正在创建一个可能会或可能不会收到绑定的视图:
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)
}
}
}
}
我想做的是,如果在此处传递到 Assignment
的绑定,则视图处于编辑模式。 newAssignment
将被设置为与 assignment
绑定相同的值,但根本不引用它。它将收集更改并在完成后将 assignment
绑定设置为等于自身,从而保存更改。使用 newAssignment
的原因是如果用户取消(此视图将是 sheet)更改将被丢弃,因为 newAssignment
是一个 @State 变量。
当视图中没有传递 Assignment
绑定时,视图处于创建模式。 newAssignment
收集更改并通过 planner
添加到商店。
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()
}
}
添加自定义初始化。这样,也不需要 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
}
.....
}
我正在创建一个可能会或可能不会收到绑定的视图:
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)
}
}
}
}
我想做的是,如果在此处传递到 Assignment
的绑定,则视图处于编辑模式。 newAssignment
将被设置为与 assignment
绑定相同的值,但根本不引用它。它将收集更改并在完成后将 assignment
绑定设置为等于自身,从而保存更改。使用 newAssignment
的原因是如果用户取消(此视图将是 sheet)更改将被丢弃,因为 newAssignment
是一个 @State 变量。
当视图中没有传递 Assignment
绑定时,视图处于创建模式。 newAssignment
收集更改并通过 planner
添加到商店。
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()
}
}
添加自定义初始化。这样,也不需要 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
}
.....
}