ios 列表视图不更新

k2fxgqgv  于 2023-02-14  发布在  iOS
关注(0)|答案(1)|浏览(190)

我有一段代码可以向注册客户端添加工作。问题是当我为客户端注册工作时,工作表被取消,列表视图没有更新。我必须从视图中退出,然后再返回,才能显示最新注册的工作。
我拥有的所有变量都是@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)
    }
}

我错过了什么?

kmbjn2e3

kmbjn2e31#

请将客户端数据作为绑定传递到详细视图。

struct AddWorkView: View {
    @Binding var clientData : ClientData
}

不知道你在客户端做什么,但是如果你使用核心数据,请检查@FetchRequest,因为它为你做了所有的繁重工作。它类似于NSFetchedResultsController
对于您的客户端设置,可能如下所示:

@FetchRequest(entity: Client.entity(), sortDescriptors: []) var locations : FetchedResults<Client>

相关问题