У меня есть 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)
}
}
}
}
}

Случайные значения и индексы не будут работать в структуре представления, данные необходимо сначала загрузить в модель, а затем написать представление, чтобы отобразить их без каких-либо дополнительных действий.
Другой вариант – заменить List{} на ScrollView(.vertical){}.





Убедитесь, что ChartData соответствует Hashable, или укажите стабильный идентификатор для ForEach.
Добавьте явный идентификатор для цикла ForEach, чтобы помочь 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)
}
}
}
}
}
Я не думаю, что это решит проблему, соответствия Identifiable должно быть достаточно.
Да, к сожалению, это не помогает
Это ==, которое только сравнивает id, скорее всего, вызовет проблемы.
Кажется, эта ошибка появляется в iOS 17.4 (см. https://forums.developer.apple.com/forums/thread/750052)
Судя по обсуждению выше:
Добавление .id(VALUE) в Chart(), где VALUE уникально для каждой диаграммы().
решит проблему
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)
}
.id(data.id) // <-------- ADD THIS
.chartYScale(domain: .automatic(includesZero: false))
.chartYAxis(.hidden)
.chartXAxis(.hidden)
.chartLegend(.hidden)
}
}
}
}
}
Я мог бы воспроизвести это, но я использовал больше статических данных, и они не только изменились, как вы говорите, но мне показалось, что они каким-то образом повторяются, поэтому у меня явно не было 90 уникальных диаграмм. Я не увидел в этом никакой закономерности, и все, что я пытаюсь записать и добавить в текстовые поля, выглядит нормально и в правильном порядке, поэтому, похоже, речь идет больше о диаграммах, чем о данных.