Ответ
UITableView — компонент для отображения одно- или многосекционных вертикальных списков.
UICollectionView — гибкий компонент для отображения данных в произвольных макетах.
Сравнительный анализ:
| Характеристика | UITableView | UICollectionView |
|---|---|---|
| Макет по умолчанию | Вертикальный список, 1 колонка | Сетка (flow layout) или кастомный |
| Ориентация | Только вертикальная | Любая (через scrollDirection) |
| Ячейки | UITableViewCell со стандартными стилями |
UICollectionViewCell полностью кастомные |
| Заголовки/подвалы | tableHeaderView, tableFooterView, секционные |
Supplementary views через UICollectionReusableView |
| Делегат | UITableViewDelegate |
UICollectionViewDelegate |
| Источник данных | UITableViewDataSource |
UICollectionViewDataSource |
| Анимации | Встроенные для строк | Кастомные через UICollectionViewLayout |
| Переиспользование | dequeueReusableCell(withIdentifier:) |
dequeueReusableCell(withReuseIdentifier:for:) |
Пример UITableView:
class SimpleListVC: UIViewController, UITableViewDataSource {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Row (indexPath.row)"
return cell
}
}
Пример UICollectionView с кастомным макетом:
class GridVC: UIViewController, UICollectionViewDataSource {
let layout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 100, height: 100)
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 5
layout.scrollDirection = .vertical
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
return layout
}()
lazy var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(CustomCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CustomCell
cell.configure(with: indexPath)
return cell
}
}
Рекомендации по выбору:
-
Используйте UITableView для:
- Простых списков (настройки, меню)
- Мастер-деталь интерфейсов
- Когда нужны стандартные стили ячеек (
.subtitle,.value1)
-
Используйте UICollectionView для:
- Сеток фотографий
- Горизонтальных каруселей
- Кастомных макетов (Pinterest-style, staggered grid)
- Анимированных переходов между layout
- Когда нужны сложные supplementary views
Производительность:
- Оба компонента эффективно переиспользуют ячейки
UICollectionViewможет быть медленнее при сложных layout вычислениях- Для больших наборов данных используйте prefetching (
UITableViewDataSourcePrefetching,UICollectionViewDataSourcePrefetching)