Ответ
Работа с ячейками в UITableView — это ядро механизма отображения списков и включает их создание, настройку, реиспользование и управление взаимодействием.
1. Регистрация и реиспользование:
Ячейка должна быть зарегистрирована для таблицы с уникальным идентификатором (reuseIdentifier). Система автоматически создает пул ячеек и выдает (dequeue) готовую или новую ячейку по запросу, что критично для производительности.
// Регистрация класса или nib-файла ячейки
tableView.register(ProfileCell.self, forCellReuseIdentifier: ProfileCell.identifier)
2. Настройка в DataSource:
Основная логика находится в методе tableView(_:cellForRowAt:).
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 1. Получение ячейки из пула
let cell = tableView.dequeueReusableCell(withIdentifier: ProfileCell.identifier, for: indexPath) as! ProfileCell
// 2. Получение модели данных для текущей строки
let user = users[indexPath.row]
// 3. Конфигурация ячейки с помощью отдельного метода
cell.configure(with: user)
return cell
}
Важно: Метод configure(with:) должен быть быстрым и идемпотентным (настраивать ячейку полностью для любого состояния).
3. Управление высотой:
- Фиксированная:
tableView.rowHeight = 60 - Динамическая (Auto Layout):
tableView.estimatedRowHeight = 100 // Приблизительная оценка для оптимизации прокрутки tableView.rowHeight = UITableView.automaticDimension // В ячейке все вертикальные constraints должны быть замкнуты от верха до низа.
4. Обработка действий (Delegate):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true) // Снять выделение
let selectedItem = data[indexPath.row]
router.openDetail(for: selectedItem) // Навигация
}
5. Оптимизация и Best Practices:
- Разделение ответственности: Класс ячейки должен заниматься только отображением. Логика загрузки данных/изображений — ответственность ViewModel/Controller.
- Неизменяемость (Immutability): В метод конфигурации передается неизменяемая (value-type) модель данных (struct).
- Подготовка к реиспользованию: Переопределите
prepareForReuse()в классе ячейки для сброса состояния (например, отмена загрузки изображения).override func prepareForReuse() { super.prepareForReuse() thumbnailImageView.image = nil dataTask?.cancel() }