ios - SwiftUI - ForEach 内两个不同子视图的数据不一致
问题描述
我正在构建一个应用程序来制作图表并计算一些基本的东西。在主屏幕上,我在 List 中有一个 ForEach 循环,显示已保存的图表。在列表中输入 NavigationLink 时,目标视图与显示的标签不对应(下面的视频)。
我不得不使用自定义 ForEach 扩展来处理绑定https://www.swiftbysundell.com/articles/bindable-swiftui-list-elements/(Apple 宣布在 iOS 15 上 ForEach 将接受绑定,但我正在开发适用于 iOS 14)。
列表的代码:
List{
ForEach($chartData.calibrations) { index, data in
VStack{
NavigationLink(
destination: DetailedChartView(index: index, currentData: data, isDetailShown: $detailVisible),
isActive: $detailVisible,
label: {
SavedListItem(index: index, savedData: self.chartData.calibrations[index])
})
.navigationBarHidden(true)
}
}.onDelete(perform: removeRows)
}.id(UUID())
.listStyle(PlainListStyle())
标签的代码 (SavedListItem)
struct SavedListItem: View {
var index: Int
var data: ChartDataObject
var formattedSlope = ""
var formattedOrigin = ""
var formattedCoef = ""
init(index: Int, savedData: ChartDataObject) {
self.data = savedData
self.index = index
self.formattedSlope = String(format: "%.2f", data.slope)
self.formattedOrigin = String(format: "%.2f", abs(data.origin))
self.formattedCoef = String(format: "%.3f", data.regressionCoef)
}
var body: some View {
HStack {
Text("\(index + 1)").bold()
VStack(alignment: .leading,spacing: 10) {
Text("\(data.name)").font(.title3)
Text("\(formatDate(data.date))")
}.padding()
Spacer()
if data.origin > 0 {
VStack {
VStack {
Text("y = \(self.formattedSlope)x + \(formattedOrigin)")
Spacer().frame(height: 10)
Text("R2 = \(formattedCoef)")
}
}
}
else if data.origin == 0 {
VStack {
VStack {
Text("y = \(formattedSlope)x")
Spacer().frame(height: 10)
Text("R2 = \(formattedCoef)")
}
}
}
else if data.origin < 0 {
VStack {
VStack {
Text("y = \(formattedSlope)x - \(formattedOrigin)")
Spacer().frame(height: 10)
Text("R2 = \(formattedCoef)")
}
}
}
else {
Text("There was an error")
}
}
.padding()
}
private func formatDate(_ date: Date) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
let dateString = dateFormatter.string(from: date)
return dateString
}
}
以及DetailedChartView的代码:
struct DetailedChartView: View {
@EnvironmentObject var calibrationsController: SavedCalibrationsController
var index: Int
@Binding var currentData: ChartDataObject
var copyData: ChartDataObject {
return currentData
}
@State var isEditing: Bool = false
@Binding var isDetailShown: Bool
var body: some View {
NavigationView{
VStack(spacing: 10) {
Text("y = \(currentData.origin) + \(currentData.slope)x")
Text("Slope: \(currentData.slope)")
Text("Origin: \(currentData.origin)")
Text("R2: \(currentData.regressionCoef)")
Divider()
RegressionChart(data: currentData).frame(height: 500)
}.navigationBarHidden(true)
}
.navigationBarTitle(currentData.name)
.toolbar(content: {
Button(action: {
self.isEditing = true
}, label: {
Text("Edit")
})
})
.sheet(isPresented: $isEditing, onDismiss: {
currentData = copyData
calibrationsController.saveData()
isEditing = false
isDetailShown = false
}, content: {
EditView(calibrationsController: calibrationsController, editVisible: $isEditing, isDetailShown: $isDetailShown, index: index, data: $currentData).environmentObject(calibrationsController)
})
}
}
当只有一项时,列表按预期运行。
这个问题让我发疯:如果我使用列表(没有 ForEach),一切都会按预期工作,但我无法更改 ForEach,因为我失去了 .onDelete() 功能,并删除了详细视图中的项目(其中有一个编辑按钮),给我一个超出范围错误的索引(另一个故事......)。
对不起,很长的帖子!
编辑:最小的可复制示例
https://drive.google.com/file/d/1WN_tGR_kVNVNqEOW054d6kMBlq8HGkF5/view?usp=sharing
解决方案
消除
isActive: $detailVisible,
在 MainList NavigationLink 中。
推荐阅读
- javascript - JS重新加载/再次返回对象值
- python - 从数据框的列中提取字符串并使用该字符串添加新列
- javascript - 从两种不同的日期方法获取毫秒
- mysql - 如何更改列以在 MySQL 中设置默认 CURRENT_TIMESTAMP
- python - 我正在尝试使用 tkinter for GUI 在 python 中为数据库编写代码。但是,当我按下提交按钮时,.get() 函数不起作用
- sorting - 我想在谷歌表中显示另一张表中分配代码的最新价格
- mingw - 使用 gcc / mingw 时应该如何链接到静态 wxWidgets 库?
- ruby-on-rails - 确认邮件到未确认邮件
- firebase - 你如何在flutter.dart中连续检查互联网访问,而不是连接
- python-3.x - 如何使用 cProfile 和多处理池?