滚动时列表单元格中的数据会发生变化

问题描述 投票:0回答:1

我有一个

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)
                }
            }
        }
    }
}
swift swiftui swiftui-charts
1个回答
0
投票

确保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)
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.