我有一段代码可以向注册客户端添加工作。问题是当我为客户端注册工作时,工作表被取消,列表视图没有更新。我必须从视图中退出,然后再返回,才能显示最新注册的工作。
我拥有的所有变量都是@State或@ObservedObject,据我所知,每当这些变量更新时,视图都会刷新。我将提供WorkListView和AddWorkView的代码。
struct WorkListView: View {
@State var client: Client
@ObservedObject var clientData = ClientData()
@State private var showingAddWork = false
@State private var additionalInfo: [String] = []
let dateFormatterStart: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "MMM d, HH:mm"
return formatter
}()
let dateFormatterEnd: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
return formatter
}()
func calculateHoursAndMinutes(startDate: Date, endDate: Date) -> String {
let interval = endDate.timeIntervalSince(startDate)
let hours = Int(interval) / 3600
let minutes = Int(interval) / 60 % 60
return "\(hours) hour(s) and \(minutes) minute(s)"
}
var body: some View {
List {
Section {
VStack(alignment: .leading) {
Text("Company")
.font(.footnote)
.foregroundColor(.secondary)
TextField("Company", text: $client.company)
.fontWeight(.semibold)
.autocorrectionDisabled(true)
}
VStack(alignment: .leading) {
Text("E-mail")
.font(.footnote)
.foregroundColor(.secondary)
TextField("E-mail", text: $client.eMail)
.fontWeight(.semibold)
.keyboardType(.emailAddress)
}
VStack(alignment: .leading) {
Text("Phone")
.font(.footnote)
.foregroundColor(.secondary)
TextField("Phone", text: $client.phone)
.fontWeight(.semibold)
.keyboardType(.numberPad)
}
VStack(alignment: .leading) {
Text("Price")
.font(.footnote)
.foregroundColor(.secondary)
TextField("Price", text: $client.price)
}
}
Section(header: Text("Performed Work")) {
ForEach(client.work.indices) { work in
VStack(alignment: .leading) {
Text("\(self.dateFormatterStart.string(from: self.client.work[work].startDate)) to \(self.dateFormatterEnd.string(from: self.client.work[work].endDate))\nDuration: \(self.calculateHoursAndMinutes(startDate: self.client.work[work].startDate, endDate: self.client.work[work].endDate))\n\(self.client.work[work].title)")
}
}
.onDelete { indexSet in
guard let workIndex = indexSet.first else { return }
self.clientData.deleteWork(for: self.client, work: self.client.work[workIndex])
}
}
}
.navigationBarTitle(client.name)
.navigationBarItems(trailing: Button(action: {
self.showingAddWork = true
}) {
Image(systemName: "plus")
})
.sheet(isPresented: $showingAddWork) {
AddWorkView(client: self.client, clientData: self.clientData, isPresented: $showingAddWork)
}
}
}
这是用于添加工作的视图
struct AddWorkView: View {
@State var client: Client
@ObservedObject var clientData = ClientData()
@Binding var isPresented: Bool
@State private var title = ""
@State private var startDate = Date()
@State private var endDate = Date()
var body: some View {
NavigationView {
Form {
TextField("Work title", text: $title)
DatePicker("Start date", selection: $startDate)
.environment(\.locale, Locale(identifier: "sv-SE"))
DatePicker("End date", selection: $endDate)
.environment(\.locale, Locale(identifier: "sv-SE"))
Button(action: {
let work = Work(title: self.title, startDate: self.startDate, endDate: self.endDate)
self.clientData.addWork(for: self.client, work: work)
self.isPresented = false
}) {
Text("Add work")
}
}
.navigationBarTitle("Add work")
.navigationBarItems(trailing: Button(action: {
self.isPresented = false
}) {
Text("Cancel")
})
}
}
}
编辑:我添加客户端的代码与此类似,该代码直接显示Added客户端。以下是添加客户端的代码:
一个二个一个一个
以下是客户端类代码:
class Client: ObservableObject, Codable, Hashable, Identifiable, Equatable {
var id = UUID()
@Published var name: String
@Published var company: String
@Published var eMail: String
@Published var phone: String
@Published var price: String
@Published var work: [Work]
init(name: String, company: String, eMail: String, phone: String, price: String) {
self.name = name
self.company = company
self.eMail = eMail
self.phone = phone
self.price = price
self.work = []
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
company = try container.decode(String.self, forKey: .company)
eMail = try container.decode(String.self, forKey: .eMail)
phone = try container.decode(String.self, forKey: .phone)
price = try container.decode(String.self, forKey: .price)
work = try container.decode([Work].self, forKey: .work)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(company, forKey: .company)
try container.encode(eMail, forKey: .eMail)
try container.encode(phone, forKey: .phone)
try container.encode(price, forKey: .price)
try container.encode(work, forKey: .work)
}
enum CodingKeys: String, CodingKey {
case name
case company
case eMail
case phone
case price
case work
}
static func == (lhs: Client, rhs: Client) -> Bool {
return lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
我错过了什么?
1条答案
按热度按时间kmbjn2e31#
请将客户端数据作为绑定传递到详细视图。
不知道你在客户端做什么,但是如果你使用核心数据,请检查@FetchRequest,因为它为你做了所有的繁重工作。它类似于NSFetchedResultsController。
对于您的客户端设置,可能如下所示: