动态更新列表

时间:2020-11-03 19:03:35

标签: swift swiftui

我希望在更改pickerSelectedItem时更新列表。我还是Swift的新手。我有一个提取行的函数,但是我觉得如果列表是@State对象,我不需要每次列表更新时都运行该函数。我的想法正确吗?有没有更好的方法来创建/调用此列表,以便它动态更新?

我正在调用的editExpense表存在类似问题。工作表解散后,我需要致电fetchRows。


import SwiftUI
import CoreData

@available(iOS 14.0, *)
struct ExpenseList: View {
    
    @State var editExpense: Expenses?
    @State var addExpense = false
    
    @Environment(\.managedObjectContext)
    var context: NSManagedObjectContext
    
    @FetchRequest(fetchRequest: Expenses.expensesList)
    private var result: FetchedResults<Expenses>

    @State var expensesList: [ExpensesList]?
    @State var sortedExpensesList: [ExpensesList]?
    
    @State var pickerSelectedItem = 0
    
    var body: some View {
        

            VStack{
                Picker(selection: $pickerSelectedItem, label: Text("")) {
                    Text("One-time").tag(0)
                    Text("Recurring").tag(1)
                }
                        .pickerStyle(SegmentedPickerStyle())
                        .padding(.horizontal, 24)
                if expensesList != nil{
                    List{
                        ForEach(self.sortedExpensesList!) { log in
                            Button(action: {
                                self.editExpense = getExpenseFromExpenseList(id: log.id)
                            }) {
                                ExpenseRow(name: log.expense, date: log.date, amount: log.cost, account: log.account)
                            }
                        }.onDelete(perform: onDelete)
                    }.environment(\.defaultMinListRowHeight, 5)
                }else {
                    Text("No One-time Expenses in this date range")
                }
                
            Spacer()
                HStack{
                    Spacer()
                    Button(action: {
                        self.addExpense.toggle()
                    }, label: {
                        Image(systemName: "plus.circle.fill").font(.system(size: 30))
                    }).padding(.all, 20)
                }
            }.onAppear(perform: fetchRows)
                
                .navigationBarItems(trailing:
                                        Button(action: {
                                            self.addExpense.toggle()
                                        }, label: {
                                            Image(systemName: "plus.circle.fill").font(.system(size: 30))
                                        }))
                
                .sheet(item: $editExpense, onDismiss: {
                    self.editExpense = nil
                })
                {
                    (log: Expenses) in
                    Print("ID: \(log.id)")
                    ExpenseDetail(
                        //context: self.context,
                        editExpense: log,
                        name: log.expenseName ?? "",
                        amount: String(log.expenseCost),
                        category: log.expenseCategory ?? "",
                        date: log.expenseDate ?? Date(),
                        account: log.expenseAccount ?? "",
                        expenseType: log.expenseType ?? "",
                        titleType: "",
                        types: ["One-time","Monthly","Per Paycheck","Weekly"]

    

                    ).environment(\.managedObjectContext, self.context).onDisappear(perform: fetchRows)
                    
                    
                    
                }
                

        

                .background(EmptyView()
                                .sheet(isPresented: $addExpense, content: {
                                    ExpenseDetail(titleType: "", types: ["One-time"]).environment(\.managedObjectContext, context).onDisappear(perform: fetchRows)
                                }))
        

        
        
        
    }
    
    func fetchRows(){
        let predicate: NSPredicate
        if self.pickerSelectedItem == 0{
            predicate = NSPredicate(format: "expenseDate >= %@ AND expenseDate < %@ AND expenseType == %@", PayScheduleForm().currentPayDate as NSDate, PayScheduleForm().nextPaydate as NSDate, "One-time")
            } else{
                predicate = NSPredicate(format: "expenseDate >= %@ AND expenseDate < %@ AND expenseType != %@", PayScheduleForm().currentPayDate as NSDate, PayScheduleForm().nextPaydate as NSDate, "One-time")
            }
        Expenses.fetchAllExpensesInDateRange(context: self.context, predicate: predicate) { (results) in
            guard !results.isEmpty else {
                self.expensesList = nil
                return
                
            }
            
            self.expensesList = results.map({ (result) -> ExpensesList in
//                print(result.self)
                return ExpensesList(id: result.id, isPaid: result.expenseIsPaid, expense: result.expenseName, cost: result.expenseCost, account: result.expenseAccount, date: result.expenseDate,expenseType: result.expenseType)
            })
            self.sortedExpensesList = self.expensesList?.sorted{
                $0.date < $1.date
            }
        }

    }
    
    func getExpenseFromExpenseList(id: UUID) -> Expenses{
        var expenses: Expenses?
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: Expenses.entity().name ?? "Expenses")
        request.predicate = NSPredicate(format: "id == %@", id as CVarArg)
        do {
            let result = try context.fetch(request)
            for data in result as! [Expenses] {
                expenses = data.self
                return expenses ?? Expenses.init()
            }
            
        } catch {
            print("Fetch failed")
        }
        return expenses ?? Expenses.init()
    }
    
    struct ExpenseList_Previews: PreviewProvider {
        static var previews: some View {
            return ExpenseList()
        }
    }
    
    
    
    
    
    private func onDelete(with indexSet: IndexSet) {
        indexSet.forEach { index in
            let listItem = sortedExpensesList![index]
            print("listItem : \(listItem.id)")
            let log = getExpenseFromExpenseList(id: listItem.id)
            print("Expenses Object ID: \(log.id)")
            if listItem.id == log.id{
                context.delete(log)
                print("trying to delete...")
                try? context.saveContext()
                fetchRows()
            }else {
                print("ID's don't match")
            }

        }

    }
    
}


struct ExpensesList: Identifiable, Equatable {
    let id: UUID
    let isPaid: Bool
    let expense: String
    let cost: Double
    let account: String
    let date: Date
    let expenseType: String
}

extension View {
    func Print(_ vars: Any...) -> some View {
        for v in vars { print(v) }
        return EmptyView()
    }
}

0 个答案:

没有答案