← Назад к вопросам

Как работает UICollectionView и чем он отличается от UITableView?

2.2 Middle🔥 141 комментариев
#CI/CD и инструменты разработки#Soft Skills и карьера#SwiftUI

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Принцип работы UICollectionView

UICollectionView — это мощный и гибкий UIKit-компонент для отображения коллекций данных с кастомной вёрсткой. Его работа строится на нескольких ключевых принципах.

Архитектура и жизненный цикл

Основу составляет паттерн делегирования (delegate) и источника данных (data source), аналогичный UITableView:

  • UICollectionViewDataSource предоставляет данные (количество секций, количество элементов, ячейки для отображения).
  • UICollectionViewDelegate обрабатывает взаимодействие пользователя (выбор, выделение, меню действий).
  • UICollectionViewDelegateFlowLayout (специальный протокол) управляет геометрией макета по умолчанию.

Важнейшее отличие — отделение логики данных от логики расположения через UICollectionViewLayout. Этот объект рассчитывает атрибуты (frame, transform, opacity) для каждого элемента, Supplementary Views (заголовки/подвалы секций) и Decoration Views (фоновые украшения).

// Пример настройки data source
class ViewController: UIViewController {
    let collectionView = UICollectionView(frame: .zero, 
                                          collectionViewLayout: UICollectionViewFlowLayout())
    var data: [String] = ["Item 1", "Item 2", "Item 3"]

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.dataSource = self
        collectionView.register(MyCell.self, forCellWithReuseIdentifier: "Cell")
    }
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, 
                        numberOfItemsInSection section: Int) -> Int {
        return data.count
    }

    func collectionView(_ collectionView: UICollectionView, 
                        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", 
                                                      for: indexPath) as! MyCell
        cell.titleLabel.text = data[indexPath.item]
        return cell
    }
}

Механизм повторного использования ячеек

Как и UITableView, UICollectionView использует механизм повторного использования (reuse pool) для эффективного управления памятью. При прокрутке ячейки, уходящие за видимую область, помещаются в очередь, а не уничтожаются, и затем переиспользуются для новых появляющихся данных.

// Регистрация ячейки для повторного использования
collectionView.register(MyCollectionViewCell.self, 
                        forCellWithReuseIdentifier: "MyCellIdentifier")

// Деактивация ячейки в data source
func collectionView(_ collectionView: UICollectionView, 
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // Ячейка автоматически создаётся или берётся из reuse pool
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCellIdentifier", 
                                                  for: indexPath)
    // Конфигурация ячейки данными
    return cell
}

Основные отличия от UITableView

  1. Гибкость макета (самое главное отличие)
    - **UITableView**: только вертикальный (реже горизонтальный) список с ячейками фиксированной ширины (равной ширине таблицы) и переменной высоты.
    - **UICollectionView**: произвольное расположение элементов благодаря отдельному объекту **UICollectionViewLayout**. Стандартный **UICollectionViewFlowLayout** предоставляет сетку с прокруткой в обоих направлениях, но можно создавать кастомные layout-ы для круговых, перекрывающихся, каскадных и любых других аранжировок.

  1. Более богатая система представлений
    - Помимо основных ячеек (cells), UICollectionView поддерживает:
        - **Supplementary Views** (заголовки и подвалы секций) — аналогичны header/footer в UITableView.
        - **Decoration Views** — чисто декоративные фоновые элементы, не привязанные к данным.
    - В UITableView есть только ячейки и заголовки/подвалы секций/таблицы.

  1. Оси и направления
    - UITableView имеет одну основную ось прокрутки (вертикальную по умолчанию).
    - UICollectionViewFlowLayout легко настраивается на горизонтальную прокрутку, а кастомные layout-ы могут реализовать любую логику перемещения.

  1. Манипуляции с данными и анимации
    - UICollectionView имеет более продвинутый API для **batch updates** (одновременное обновление, удаление, вставка секций и элементов) с встроенными анимациями.
    - Поддержка **drag & drop** (с iOS 11) и **reordering** в реальном времени более глубокая.

  1. Настройка внешнего вида ячеек
    - В UITableView ячейка часто конфигурируется через встроенные стили (`.default`, `.subtitle` и т.д.).
    - В UICollectionView ячейка — это **UIView**, которую разработчик проектирует и верстает полностью самостоятельно, что даёт полную свободу.

Когда что использовать?

  • Используйте UITableView для:
    - Однородных списков (лента сообщений, контакты, настройки).
    - Сценариев, где достаточно простого вертикального скролла.
    - Быстрой реализации стандартного интерфейса (например, Master-Detail).

  • Используйте UICollectionView для:
    - Сеток изображений (галерея, фотоальбом).
    - Любых нелинейных макетов (пейзажная лента, Pinterest-подобная раскладка).
    - Кастомных интерфейсов, где элементы должны располагаться по сложной геометрии.
    - Интерфейсов с горизонтальной прокруткой внутри ячеек или секций.

Итог: UITableView — это специализированный инструмент для списков, тогда как UICollectionView — это универсальный, расширяемый фреймворк для отображения любых коллекций данных с произвольной вёрсткой. Многие современные интерфейсы (например, главный экран iOS) построены именно на UICollectionView, что демонстрирует его мощность и гибкость.