ForEach с id по индексу: что ломается при вставке элемента в начало списка
Экран чата, новые сообщения добавляются в начало массива:
ForEach(0..<messages.count, id: \.self) { index in
MessageRow(message: messages[index])
}
Пользователи жалуются: при появлении нового сообщения анимация дёргается, а раскрытые ранее строки схлопываются или раскрываются не там. В чём корень проблемы?
- Идентичность строки привязана к позиции в массиве, а не к самому сообщению
- ForEach по диапазону не поддерживает больше десяти элементов, для длинных списков нужен List
- Ключ id: \.self заставляет SwiftUI сравнивать вью по содержимому, из-за чего перерисовка не происходит вовсе
- Сообщения хранятся в массиве структур, а диффинг в SwiftUI работает только для ссылочных типов
