数据更改后 SwiftUI 列表未更新。 (需要切换视图)
SwiftUI List not updating after Data change. (Needs switching the view)
我正在尝试更改 SwiftUI 列表以在点击列表中的复选框按钮后进行更新。
当我点击列表行复选框按钮时,我调用一个函数来将直接行设置为选中,哪个 ID 小于所选行。我可以将 ArrayList 修改为 selected = 0 到 selected = 1。但是由于我的列表是 Published var,它应该将更改发送到我的列表视图。但事实并非如此。
这是我所做的:
// 视图模型
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: {[=10=].ispID == ispID}) {
self.changeSelection(row: row)
}
}
}
func changeSelection(row: Int) {
if invoiceList[row].selected == 0 {
let selectedRows = invoiceList.map({ [=10=].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({ [=10=].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?
}
您需要使用绑定而不是外部注入状态(设置为值的副本),即
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])
}
}
我正在尝试更改 SwiftUI 列表以在点击列表中的复选框按钮后进行更新。 当我点击列表行复选框按钮时,我调用一个函数来将直接行设置为选中,哪个 ID 小于所选行。我可以将 ArrayList 修改为 selected = 0 到 selected = 1。但是由于我的列表是 Published var,它应该将更改发送到我的列表视图。但事实并非如此。
这是我所做的:
// 视图模型
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: {[=10=].ispID == ispID}) {
self.changeSelection(row: row)
}
}
}
func changeSelection(row: Int) {
if invoiceList[row].selected == 0 {
let selectedRows = invoiceList.map({ [=10=].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({ [=10=].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?
}
您需要使用绑定而不是外部注入状态(设置为值的副本),即
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])
}
}