Вступить в клуб →
средняявопросUIKit и SwiftUI: экраны и состояние

ForEach с id по индексу: что ломается при вставке элемента в начало списка

Экран чата, новые сообщения добавляются в начало массива:

ForEach(0..<messages.count, id: \.self) { index in
    MessageRow(message: messages[index])
}

Пользователи жалуются: при появлении нового сообщения анимация дёргается, а раскрытые ранее строки схлопываются или раскрываются не там. В чём корень проблемы?

  • Идентичность строки привязана к позиции в массиве, а не к самому сообщению
  • ForEach по диапазону не поддерживает больше десяти элементов, для длинных списков нужен List
  • Ключ id: \.self заставляет SwiftUI сравнивать вью по содержимому, из-за чего перерисовка не происходит вовсе
  • Сообщения хранятся в массиве структур, а диффинг в SwiftUI работает только для ссылочных типов

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела