SwiftUI 列表在数据更改后没有更新 (需要切换视图)

3
我正在尝试更改SwiftUI列表,以便在单击列表中的复选框按钮后进行更新。 当我点击列表行复选框按钮时,我调用一个函数将ID小于所选ID的行设置为已选中。我可以将ArrayList修改为selected = 1而不是selected = 0。但是,由于我的列表是Published var,因此它应该向我的列表视图发送更改通知。但它没有这样做。
这是我所做的:
// ViewModel
import Foundation
import Combine

class BillingViewModel: ObservableObject {
    
    @Published var invoiceList = [InvoiceModel](){
        didSet {
            self.didChange.send(true)
        }
    }
    
    @Published var shouldShow = true
    
    let didChange = PassthroughSubject<Bool, Never>()
    
    init() {
        setValues()
    }
    
    func setValues() {
        for i in 0...10 {
            invoiceList.append(InvoiceModel(ispID: 100+i, selected: 0, invoiceNo: "Invoice No: \(100+i)"))
        }
    }
    
    func getCombinedBalance(ispID: Int) {
        DispatchQueue.main.async {
            
            if let row = self.invoiceList.firstIndex(where: {$0.ispID == ispID}) {
                self.changeSelection(row: row)
            }
            
        }
    }
    
    func changeSelection(row: Int) {
        if invoiceList[row].selected == 0 {
            
            let selectedRows = invoiceList.map({ $0.ispID ?? 0 <= invoiceList[row].ispID ?? 0 })
            
            print(selectedRows)
            
            for index in 0..<invoiceList.count {
                if selectedRows[index] {
                    invoiceList[index].selected = 1
                } else {
                    invoiceList[index].selected = 0
                }
            }
            
        } else {
            
            let selectedRows = invoiceList.map({ $0.ispID ?? 0 <= invoiceList[row].ispID ?? 0 })
            
            print(selectedRows)
            
            for index in 0..<invoiceList.count {
                if selectedRows[index] {
                    invoiceList[index].selected = 1

                } else {
                    invoiceList[index].selected = 0
                }
            }
        }
    }
    
}

// 列表视图

import SwiftUI

struct ContentView: View {
    
    @StateObject var billingViewModel = BillingViewModel()
    @State var shouldShow = true
    
    var body: some View {
        NavigationView {
            ZStack {
                VStack {
                    List {
                        ForEach(billingViewModel.invoiceList) { invoice in
                            NavigationLink(
                                destination: InvoiceDetailsView(billingViewModel: billingViewModel)) {
                                invoiceRowView(billingViewModel: billingViewModel, invoice: invoice)
                            }
                        }
                        
                    }
                }
            }.navigationBarTitle(Text("Invoice List"))
        }
        
    }
}

// 发票行视图

import SwiftUI

struct invoiceRowView: View {
    
    @StateObject var billingViewModel: BillingViewModel
    @State var invoice: InvoiceModel
    
    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Button(action: {
                    if invoice.selected == 0 {
                        print(invoice)
                        billingViewModel.getCombinedBalance(ispID: invoice.ispID ?? 0)
                    } else {
                        print(invoice)
                        billingViewModel.getCombinedBalance(ispID: invoice.ispID ?? 0)
                    }
                }, label: {
                    Image(systemName: invoice.selected == 0 ? "checkmark.circle" : "checkmark.circle.fill")
                        .resizable()
                        .frame(width: 32, height: 32, alignment: .center)
                    
                }).buttonStyle(PlainButtonStyle())
                
                Text(invoice.invoiceNo ?? "Hello, World!").padding()
                
                Spacer()
            }
        }
    }
}

//数据模型

import Foundation

struct InvoiceModel: Codable, Identifiable {
    var id = UUID()
    var ispID: Int?
    var selected: Int?
    var invoiceNo: String?
}

1
你能展示一下InvoiceModel的代码吗? - Asperi
import Foundationstruct InvoiceModel: Codable, Identifiable { var id = UUID() var ispID: Int? var selected: Int? var invoiceNo: String? } - MD. Shakhawat Hossain Shahin
1个回答

4
你需要使用绑定(binding)而不是外部注入的状态(仅设置为值的副本),即:
struct invoiceRowView: View {
    
    @StateObject var billingViewModel: BillingViewModel
    @Binding var invoice: InvoiceModel

    // .. other code

因此,在父视图中注入绑定

ForEach(billingViewModel.invoiceList.indices, id: \.self) { index in
    NavigationLink(
        destination: InvoiceDetailsView(billingViewModel: billingViewModel)) {
        invoiceRowView(billingViewModel: billingViewModel, invoice: $billingViewModel.invoiceList[index])
    }
}

我已经尝试解决这个问题2天了。感谢您的帮助... - MD. Shakhawat Hossain Shahin
我很惊讶这个没有得到更多的赞。这非常有用! :) - Chris Prince

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接