我有一个
List
,其中每个单元格都有一个图表。列表的数据生成一次并存储在 chartData
属性中。然而,有一个错误。滚动列表时,单元格中的图表会改变位置:如果我们将列表向下滚动几个单元格然后返回到顶部,那么第一个单元格将具有与滚动之前完全不同的图表。然而,只有图表改变,数字Text
保持不变
struct ChartData: Identifiable {
let id = UUID()
let number: Int
let data: [Double]
var isPositiveTrend: Bool {
return data.last ?? 0 > data.first ?? 0
}
}
struct ContentView: View {
let chartData: [ChartData] = (0..<90).map { index in
ChartData(number: index, data: (0..<12).map { _ in Double.random(in: 1...10) })
}
var body: some View {
List {
ForEach(chartData) { data in
HStack {
Text("\(data.number)")
Chart(Array(zip(data.data.indices, data.data)), id: \.0) { idx, val in
LineMark(
x: .value("index", idx),
y: .value("value", val)
)
.interpolationMethod(.catmullRom)
.foregroundStyle(data.isPositiveTrend ? .green : .red)
}
.chartYScale(domain: .automatic(includesZero: false))
.chartYAxis(.hidden)
.chartXAxis(.hidden)
.chartLegend(.hidden)
}
}
}
}
}
确保ChartData符合Hashable或为ForEach提供稳定的id。
为 ForEach 循环添加显式 id,以帮助 SwiftUI 正确管理视图。
struct ChartData: Identifiable, Hashable {
let id = UUID()
let number: Int
let data: [Double]
var isPositiveTrend: Bool {
return data.last ?? 0 > data.first ?? 0
}
static func == (lhs: ChartData, rhs: ChartData) -> Bool {
return lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
struct ContentView: View {
let chartData: [ChartData] = (0..<90).map { index in
ChartData(number: index, data: (0..<12).map { _ in Double.random(in: 1...10) })
}
var body: some View {
List {
ForEach(chartData, id: \.self) { data in
HStack {
Text("\(data.number)")
Chart(Array(zip(data.data.indices, data.data)), id: \.0) { idx, val in
LineMark(
x: .value("index", idx),
y: .value("value", val)
)
.interpolationMethod(.catmullRom)
.foregroundStyle(data.isPositiveTrend ? .green : .red)
}
.chartYScale(domain: .automatic(includesZero: false))
.chartYAxis(.hidden)
.chartXAxis(.hidden)
.chartLegend(.hidden)
}
}
}
}
}