UICollectionView — iOS üçün UIKit-in güclü komponenti, obyekt kolleksiyalarının şəbəkələr, siyahılar və xüsusi maketlər şəklində göstərilməsini idarə edir. UITableView-dən fərqli olaraq, UICollectionView bir sütunla məhdudlaşmır: UICollectionViewLayout vasitəsilə elementlərin ixtiyari yerləşdirilməsini dəstəkləyir. UICollectionView-in mahiyyətini, FlowLayout və CompositionalLayout-un necə işlədiyini və Swift-də xüsusi hüceyrələrin yaradılmasını izah edirik. IT Sectr-də UICollectionView-dan qalereyalar, kataloqlar və elan lövhələri üçün istifadə edirik. Cədvəllərlə müqayisə üçün UITableView haqqında məqaləni oxuyun.
Əsas məqamlar
UICollectionView — iOS 6-da (2012) təqdim edilmiş UIKit freymvorkundan bir sinifdir. O, UICollectionViewLayout obyekti tərəfindən idarə olunan çevik maketdə sıralanmış hüceyrələr kolleksiyasını (UICollectionViewCell) göstərir. UICollectionView UITableView ilə eyni tapşırığı həll edir (siyahılar), lakin elementlərin ixtiyari yerləşdirilməsi ilə: şəbəkələr, karusellər, mozaikalar, kaskadlar.
Arxitektura UICollectionView MVC nümunəsi üzərində qurulub: məlumatlar — DataSource-da, maket — UICollectionViewLayout-da, davranış — UICollectionViewDelegate-da. Bu bölgü məlumat kodunu dəyişmədən maketləri dəyişməyə imkan verir. Apple-a görə (WWDC 2025), App Store-un top 100-dən 72% iOS tətbiqi məzmun göstərmək üçün UICollectionView-dan istifadə edir. CollectionView iOS 6-dan çoxsütunlu maketləri dəstəkləyir, iOS 13-dən isə mürəkkəb bölmələr üçün CompositionalLayout aldı.
UICollectionView UITableView kimi təkrar istifadə olunan hüceyrələr hovuzundan (reuse queue) istifadə edir. dequeueReusableCell(withReuseIdentifier:for:) metodu hovuzdan hüceyrə qaytarır və ya hovuz boşdursa yenisini yaradır. UITableView-dən fərqli olaraq, UICollectionViewCell hüceyrəsinin daxili contentView-i var, ona bütün subview-lər əlavə edilməlidir — hüceyrəyə birbaşa əlavə etməyin, çünki contentView seçim və redaktə animasiyasına cavabdehdir.
UICollectionViewFlowLayout — iOS 6-dan işləyən standart maket. Elementləri sətirlər üzrə (flow) yerləşdirir, hüceyrə ölçüsü, sürüşdürmə istiqaməti, minimal intervallar və bölmələr təyin etmək imkanı ilə. UICollectionViewCompositionalLayout — maketi blokların kombinasiyası ilə təsvir edən müasir maket (iOS 13+): qrup → bölmə → maket, burada hər qrup üfüqi, şaquli və ya xüsusi ola bilər.
| Parametr | UICollectionViewFlowLayout | UICollectionViewCompositionalLayout |
|---|---|---|
| Minimal versiya | iOS 6 | iOS 13 |
| Mürəkkəb maketlər | Yalnız sadə şəbəkə və ya siyahı | Müxtəlif maketli bölmələr, qruplar, karusellər |
| Adaptivlik | Deleqat ölçüsü vasitəsilə | NSCollectionLayoutDimension.fractionalWidth/Height |
| Performans | Bütün görünən elementləri render edir | Tənbəl bölmə yaratma |
| iPad dəstəyi | Əl adaptasiyası tələb edir | fractionalWidth vasitəsilə adaptiv qruplar |
| Yazma çətinliyi | Aşağı (5–10 sətir) | Orta (15–30 sətir) |
// FlowLayout ilə əsas UICollectionView
class ViewController: UIViewController {
private var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumInteritemSpacing = 8
layout.minimumLineSpacing = 12
layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
layout.itemSize = CGSize(width: view.frame.width - 32, height: 100)
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
collectionView.dataSource = self
view.addSubview(collectionView)
}
}
// DataSource
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int { 20 }
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
as! CustomCell
cell.configure(with: "Item \(indexPath.row)")
return cell
}
}
Apple tövsiyəsi (WWDC 2025): yeni layihələr üçün CompositionalLayout-dan istifadə edin. Adaptiv maketlər üçün daha çox imkan verir, UIKit və SwiftUI ilə UICollectionView.Representable vasitəsilə daha yaxşı işləyir və avtomatik ölçülü bölmə başlıqlarını dəstəkləyir. FlowLayout-u eyni hüceyrələrdən ibarət sadə şəbəkə ekranları və iOS 12 və aşağı minimal versiya üçün saxlayın.
UICollectionViewCell — UICollectionView hüceyrələri üçün əsas sinifdir. Hər hüceyrədə contentView (əsas konteyner), backgroundView (standart fon), selectedBackgroundView (seçim zamanı fon) var. Hüceyrənin görünüşünü contentView daxilində tənzimləyin — heç vaxt subview-ləri birbaşa UICollectionViewCell-ə əlavə etməyin.
// Konfiqurasiya ilə xüsusi hüceyrə
class ProductCell: UICollectionViewCell {
private let imageView = UIImageView()
private let titleLabel = UILabel()
private let priceLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
contentView.addSubview(imageView)
contentView.addSubview(titleLabel)
contentView.addSubview(priceLabel)
// Auto Layout constraints
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor),
titleLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 8),
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8),
titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8),
priceLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4),
priceLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8)
])
}
func configure(with product: Product) {
imageView.image = UIImage(named: product.imageName)
titleLabel.text = product.title
priceLabel.text = product.price
}
}
UICollectionViewDelegate seçim, vurğulama, kontekst menyuları və yenidən sıralama üçün metodlar təqdim edir. UITableView-dən fərqli olaraq, UICollectionViewDelegate təkcə elementə kliki deyil, həm də uzun basmağı (UIContextMenuInteraction vasitəsilə kontekst menyusu) idarə etməyə imkan verir. Klikləməni idarə etmək üçün collectionView(_:didSelectItemAt:) metodunu tətbiq edin — seçim animasiyası bitdikdə çağırılır.
UICollectionViewDiffableDataSource — iOS 13-də təqdim edilmiş UICollectionViewDataSource-un tip-təhlükəsiz əvəzedicisidir. cellForItemAt vasitəsilə əl ilə idarə etmək əvəzinə, DiffableDataSource NSDiffableDataSourceSnapshot-dan istifadə edir — köhnə və yeni vəziyyət arasındakı fərqi avtomatik hesablayan və dəyişiklikləri animasiya edən məlumat vəziyyətinin şəkli.
// Bölmələrlə DiffableDataSource
enum Section {
case featured, recommended, categories
}
class ModernDataSource: UIViewController {
private var dataSource: UICollectionViewDiffableDataSource<Section, Product>!
override func viewDidLoad() {
super.viewDidLoad()
configureDataSource()
applyInitialSnapshot()
}
private func configureDataSource() {
let cellRegistration = UICollectionView.CellRegistration<ProductCell, Product> { cell, _, product in
cell.configure(with: product)
}
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) {
collectionView, indexPath, product in
collectionView.dequeueConfiguredReusableCell(
using: cellRegistration, for: indexPath, item: product
)
}
}
private func applyInitialSnapshot() {
var snapshot = NSDiffableDataSourceSnapshot<Section, Product>()
snapshot.appendSections([.featured, .recommended, .categories])
snapshot.appendItems(featuredProducts, toSection: .featured)
snapshot.appendItems(recommendedProducts, toSection: .recommended)
snapshot.appendItems(categories, toSection: .categories)
dataSource.apply(snapshot, animatingDifferences: true)
}
// Avtomatik animasiya ilə yeniləmə
func updateProducts(_ products: [Product]) {
var snapshot = dataSource.snapshot()
snapshot.deleteItems(snapshot.itemIdentifiers)
snapshot.appendItems(products)
dataSource.apply(snapshot, animatingDifferences: true)
}
}
DiffableDataSource üstünlükləri: (1) avtomatik animasiya — insert, delete, reload standart animasiya ilə baş verir; (2) tip təhlükəsizliyi — bölmələr və elementlər tipləşdirilib, runtime xətası əvəzinə kompilasiya xətası; (3) Snapshot — vəziyyət şəklini saxlamaq, geri qaytarmaq, müqayisə etmək olar; (4) performans — DiffableDataSource minimal dəyişiklik dəstini hesablamaq üçün Hellir alqoritmindən istifadə edir. Apple (WWDC 2024) bütün yeni UICollectionView-lər üçün DiffableDataSource tövsiyə edir, köhnə DataSource-u isə yalnız iOS 12 və daha köhnə versiyalar üçün saxlayın.
UICollectionViewLayout — kolleksiya elementlərinin yerləşməsini tam idarə edən abstrakt sinifdir. FlowLayout və CompositionalLayout uyğun gəlmirsə (məsələn, dairəvi maket, spiral, diaqram), UICollectionViewLayout-un alt sinfini yaradın və maket hazırlığı metodlarını override edin.
// Xüsusi dairəvi maket
class CircularLayout: UICollectionViewLayout {
private var attributesCache: [UICollectionViewLayoutAttributes] = []
private let radius: CGFloat = 120
override func prepare() {
super.prepare()
attributesCache.removeAll()
guard let collectionView else { return }
let count = collectionView.numberOfItems(inSection: 0)
let center = CGPoint(x: collectionView.bounds.midX, y: collectionView.bounds.midY)
for i in 0..<count {
let indexPath = IndexPath(item: i, section: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
let angle = (CGFloat(i) / CGFloat(count)) * 2 * .pi
attributes.center = CGPoint(
x: center.x + radius * cos(angle),
y: center.y + radius * sin(angle)
)
attributes.size = CGSize(width: 60, height: 60)
attributesCache.append(attributes)
}
}
override var collectionViewContentSize: CGSize {
collectionView?.bounds.size ?? .zero
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
attributesCache.filter { $0.frame.intersects(rect) }
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
attributesCache[indexPath.item]
}
}
Performans: xüsusi UICollectionViewLayout prepare() də atributları keşləməli və layoutAttributesForItem(at:) də O(1) ilə qaytarmalıdır. 1000+ elementli kolleksiyalar üçün shouldInvalidateLayout(forBoundsChange:) vasitəsilə inkremental keş yeniləməsindən istifadə edin — bu, sürüşdürmə zamanı bütün maketi yenidən hesablamamağa imkan verir. Apple (WWDC 2023) xüsusi maketlər əvəzinə CompositionalLayout tövsiyə edir: o, sıfırdan maket yazmağa ehtiyac olmadan ssenarilərin 95%-ni əhatə edir.
UITableView və UICollectionView — siyahıları göstərmək üçün iki əsas UIKit komponenti. UITableView daha sadədir və təksütunlu siyahılar üçün nəzərdə tutulub. UICollectionView daha çevikdir və istənilən maketləri dəstəkləyir. Onlar arasında seçim məlumatların vizual strukturundan və tələb olunan fərdiləşdirmədən asılıdır.
| Parametr | UITableView | UICollectionView |
|---|---|---|
| Maket | Yalnız şaquli siyahı | Siyahı, şəbəkə, kaskad, karusel, xüsusi |
| Mürəkkəblik | Aşağı (sadə DataSource) | Orta (Layout + DataSource + Delegate) |
| Standart hüceyrə | 4 stil (basic, subtitle, value1, value2) | Yalnız boş (contentView vasitəsilə xüsusi) |
| Redaktə rejimi | Daxili (delete, move, insert) | Əl ilə tətbiq tələb edir |
| Header/Footer | Daxili (viewForHeaderInSection) | Köməkçi görünüşlər vasitəsilə |
| Performans | Siyahılar üçün yüksək | İstənilən maketlər üçün yüksək |
| iOS 6+ | iOS 2-dən mövcud | iOS 6-dan mövcud |
Praktik qayda: ekran sadə sətir siyahısıdırsa (parametrlər, kontaktlar, menyu) UITableView-dan istifadə edin. Ekran şəbəkə, üfüqi sürüşdürmə, karusel, müxtəlif hüceyrə ölçüləri və ya mürəkkəb qruplaşdırma tələb edirsə UICollectionView-dan istifadə edin. iOS 14-dən etibarən UITableView də UICollectionLayoutListConfiguration vasitəsilə CompositionalLayout dəstəyi aldı, bu da hər iki komponentin üstünlüklərini birləşdirməyə imkan verir.
Tez-tez verilən suallar
UICollectionViewFlowLayout-da scrollDirection = .horizontal təyin edin. CompositionalLayout üçün qrupun adaptiv eni üçün fractionalWidth ilə NSCollectionLayoutSize istifadə edin. Üfüqi sürüşdürmə karusellər, qalereyalar və kateqoriyalar üçün yaxşıdır. Səhifələmə üçün collectionView.isPagingEnabled = true təyin edin və ya itemSize = bounds.width ilə UICollectionViewFlowLayout istifadə edin.
Yoxlayın: (1) hüceyrə register(_:forCellWithReuseIdentifier:) vasitəsilə qeydiyyatdan keçib, (2) DataSource element sayını > 0 qaytarır, (3) hüceyrə düzgün reuseIdentifier ilə dequeued edilib, (4) itemSize sıfır deyil (FlowLayout üçün). Tipik səhv — itemSize = CGSize.zero, bu halda hüceyrələrin hündürlüyü sıfır olur. itemSize-i açıq şəkildə təyin edin və ya collectionView(_:layout:sizeForItemAt:) deleqatını tətbiq edin.
FlowLayout üçün: layout.minimumInteritemSpacing (sətirdə elementlər arasında) və layout.minimumLineSpacing (sətirlər arasında). CompositionalLayout üçün: NSCollectionLayoutGroup.interItemSpacing və qrup/bölmədə contentInsets. sectionInset bölmənin xarici boşluqlarını təyin edir. Safe Area-nın düzgün nəzərə alınması üçün sectionInsetReference = .fromContentInset istifadə edin.
Qrup animasiyaları üçün performBatchUpdates istifadə edin: collectionView.performBatchUpdates { insertItems, deleteItems, reloadItems }. Təhlükəsiz və animasiyalı yeniləmə üçün UICollectionViewDiffableDataSource istifadə edin: dataSource.apply(snapshot, animatingDifferences: true) çağırın — bütün dəyişikliklər avtomatik hesablanacaq və əl ilə insert/delete olmadan tətbiq ediləcək.
SwiftUI-də UICollectionView-un analoqu LazyVGrid və LazyHGrid-dir (iOS 14+). SwiftUI Grid yazmaq üçün daha sadədir (deklarativ sintaksis), lakin 500+ element və maket fərdiləşdirilməsi üçün UICollectionView-dan zəifdir. Mürəkkəb kolleksiyalar üçün UIViewRepresentable vasitəsilə UICollectionView istifadə edin. IT Sectr layihələrində kataloqlar və qalereyalar üçün UICollectionView, sadə ekranlar üçün SwiftUI Grid seçirik.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun