UICollectionView — lényeg, gyűjtemények és FlowLayout iOS-ben

Szerző: IT Sectr Megjelenés: 2026-02-23 Olvasási idő: 9 perc

UICollectionView — egy hatékony UIKit komponens iOS-hez, amely objektumgyűjtemények megjelenítését kezeli rácsok, listák és egyéni elrendezések formájában. A UITableView-től eltérően az UICollectionView nem korlátozódik egy oszlopra: támogatja az elemek tetszőleges elhelyezését az UICollectionViewLayout segítségével. Elmagyarázzuk az UICollectionView lényegét, hogyan működik a FlowLayout és a CompositionalLayout, és hogyan hozhatók létre egyéni cellák Swift-ben. Az IT Sectr-ben UICollectionView-t használunk galériákhoz, katalógusokhoz és hirdetőtáblákhoz. A táblázatokkal való összehasonlításhoz olvassa el a UITableView-ról szóló cikket.

Főbb pontok

  • UICollectionView — UIKit komponens gyűjtemények megjelenítéséhez rácsok, listák és tetszőleges elrendezések formájában.
  • UICollectionViewFlowLayout — szabványos elrendezés irány, cellaméretek és távolságok támogatásával.
  • UICollectionViewCompositionalLayout — modern elrendezés (iOS 13+) összetett szakaszokhoz blokkokkal, körhintákkal és csoportokkal.
  • UICollectionViewDiffableDataSource — típusbiztos DataSource automatikus változásszámítással (iOS 13+).
  • UICollectionViewCell — alap cella beépített backgroundView, selectedBackgroundView és contentView elemekkel.

Mi az UICollectionView iOS-ben?

UICollectionView — egy osztály az UIKit keretrendszerből, amelyet iOS 6-ban (2012) vezettek be. Rendezett cellagyűjteményt (UICollectionViewCell) jelenít meg egy rugalmas elrendezésben, amelyet egy UICollectionViewLayout objektum kezel. Az UICollectionView ugyanazt a feladatot oldja meg, mint a UITableView (listák), de az elemek tetszőleges elhelyezésével: rácsok, körhinták, mozaikok, kaszkádok.

Architektúra Az UICollectionView az MVC mintára épül: adatok — a DataSource-ben, elrendezés — az UICollectionViewLayout-ban, viselkedés — az UICollectionViewDelegate-ben. Ez a szétválasztás lehetővé teszi az elrendezések cseréjét az adatkód módosítása nélkül. Az Apple szerint (WWDC 2025) az App Store top 100-as listáján lévő iOS-alkalmazások 72%-a használ UICollectionView-t a tartalom megjelenítésére. A CollectionView iOS 6 óta támogatja a többoszlopos elrendezéseket, és iOS 13-tól megkapta a CompositionalLayout-ot összetett szakaszokhoz.

A cella életciklusa

Az UICollectionView újrafelhasználható cellák készletét használja (reuse queue), hasonlóan a UITableView-hez. A dequeueReusableCell(withReuseIdentifier:for:) metódus visszaad egy cellát a készletből, vagy újat hoz létre, ha a készlet üres. A UITableView-től eltérően az UICollectionViewCell rendelkezik egy beépített contentView-vel, amelyhez az összes subview-t hozzá kell adni — ne adja hozzá őket közvetlenül a cellához, mert a contentView felelős a kijelölés és szerkesztés helyes animációjáért.

FlowLayout vs CompositionalLayout: összehasonlítás

UICollectionViewFlowLayout — szabványos elrendezés, amely iOS 6 óta működik. Sorokba rendezi az elemeket (flow) a cellaméret, görgetési irány, minimális távolságok és szakaszok beállításának lehetőségével. UICollectionViewCompositionalLayout — modern elrendezés (iOS 13+), amely az elrendezést blokkok kombinációjával írja le: csoport → szakasz → elrendezés, ahol minden csoport lehet vízszintes, függőleges vagy egyéni.

ParaméterUICollectionViewFlowLayoutUICollectionViewCompositionalLayout
Minimális verzióiOS 6iOS 13
Összetett elrendezésekCsak egyszerű rács vagy listaKülönböző elrendezésű szakaszok, csoportok, körhinták
AdaptivitásA delegált méretén keresztülNSCollectionLayoutDimension.fractionalWidth/Height
TeljesítményAz összes látható elemet rendereliLusta szakaszlétrehozás
iPad támogatásKézi adaptációt igényelAdaptív csoportok fractionalWidth segítségével
Írási komplexitásAlacsony (5–10 sor)Közepes (15–30 sor)
swift
// Alap UICollectionView FlowLayout-tal
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 ajánlása (WWDC 2025): új projektekhez használja a CompositionalLayout-ot. Több lehetőséget biztosít az adaptív elrendezésekhez, jobban működik az UIKit és SwiftUI elemekkel az UICollectionView.Representable segítségével, és támogatja az automatikus méretű szakaszfejléceket. Hagyja a FlowLayout-ot egyszerű, azonos cellákból álló rácsos képernyőkhöz és iOS 12-es vagy alacsonyabb minimális verzióhoz.

UICollectionViewCell és UICollectionViewDelegate

UICollectionViewCell — az UICollectionView celláinak alaposztálya. Minden cella tartalmaz egy contentView-t (fő tároló), backgroundView-t (alapértelmezett háttér), selectedBackgroundView-t (háttér kijelöléskor). Állítsa be a cella megjelenését a contentView-n belül — soha ne adjon hozzá subview-okat közvetlenül az UICollectionViewCell-hez.

swift
// Egyéni cella konfigurációval
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 módszereket biztosít a kijelölés, kiemelés, helyi menük és átrendezés kezeléséhez. A UITableView-től eltérően az UICollectionViewDelegate nem csak az elemre kattintást, hanem a hosszú lenyomást is vezérelheti (helyi menü az UIContextMenuInteraction segítségével). A kattintás kezeléséhez implementálja a collectionView(_:didSelectItemAt:) metódust — ez a kijelölési animáció befejezésekor hívódik meg.

UICollectionViewDiffableDataSource: modern DataSource

UICollectionViewDiffableDataSource — az UICollectionViewDataSource típusbiztos helyettesítője, amelyet iOS 13-ban vezettek be. A cellák manuális kezelése helyett a cellForItemAt segítségével a DiffableDataSource az NSDiffableDataSourceSnapshot-t használja — az adatállapot pillanatképét, amely automatikusan kiszámítja a régi és új állapot közötti különbséget és animálja a változásokat.

swift
// DiffableDataSource szakaszokkal
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)
    }

    // Frissítés automatikus animációval
    func updateProducts(_ products: [Product]) {
        var snapshot = dataSource.snapshot()
        snapshot.deleteItems(snapshot.itemIdentifiers)
        snapshot.appendItems(products)
        dataSource.apply(snapshot, animatingDifferences: true)
    }
}

A DiffableDataSource előnyei: (1) automatikus animáció — az insert, delete, reload alapértelmezett animációval történik; (2) típusbiztonság — a szakaszok és elemek tipizáltak, fordítási hibák a runtime hibák helyett; (3) Snapshot — az állapot pillanatképét el lehet menteni, visszavonni, összehasonlítani; (4) teljesítmény — a DiffableDataSource a Hellir-algoritmust használja a minimális változtatáskészlet kiszámításához. Az Apple (WWDC 2024) a DiffableDataSource-t ajánlja minden új UICollectionView-hoz, a régi DataSource-t csak iOS 12 és régebbi verziókhoz hagyja meg.

Egyéni elrendezés létrehozása UICollectionViewLayout segítségével

UICollectionViewLayout — absztrakt osztály, amely teljes mértékben vezérli a gyűjtemény elemeinek elhelyezését. Ha a FlowLayout és a CompositionalLayout nem megfelelő (például kör alakú elrendezés, spirál, diagram), hozzon létre egy alosztályt az UICollectionViewLayout-ból, és írja felül az elrendezés előkészítésének metódusait.

swift
// Egyéni kör alakú elrendezés
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]
    }
}

Teljesítmény: az egyéni UICollectionViewLayout-nak gyorsítótáraznia kell az attribútumokat a prepare() metódusban, és O(1) időben vissza kell adnia azokat a layoutAttributesForItem(at:) metódusban. 1000+ elemű gyűjteményekhez használjon inkrementális gyorsítótár-frissítést a shouldInvalidateLayout(forBoundsChange:) segítségével — ez lehetővé teszi, hogy ne számítsa újra a teljes elrendezést görgetés közben. Az Apple (WWDC 2023) a CompositionalLayout-ot ajánlja az egyéni elrendezések helyett: az esetek 95%-át lefedi anélkül, hogy elrendezést kellene írnia a nulláról.

UICollectionView vs UITableView: mikor mit válasszunk

UITableView és UICollectionView — a két fő UIKit komponens listák megjelenítéséhez. A UITableView egyszerűbb, és egyoszlopos listákhoz készült. Az UICollectionView rugalmasabb, és bármilyen elrendezést támogat. A köztük való választás az adatok vizuális szerkezetétől és a szükséges testreszabástól függ.

ParaméterUITableViewUICollectionView
ElrendezésCsak függőleges listaLista, rács, kaszkád, körhinta, egyéni
KomplexitásAlacsony (egyszerű DataSource)Közepes (Layout + DataSource + Delegate)
Alapértelmezett cella4 stílus (basic, subtitle, value1, value2)Csak üres (egyéni a contentView segítségével)
Szerkesztési módBeépített (delete, move, insert)Kézi implementációt igényel
Header/FooterBeépített (viewForHeaderInSection)Kiegészítő nézetek segítségével
TeljesítményMagas listákhozMagas bármilyen elrendezéshez
iOS 6+iOS 2-től elérhetőiOS 6-tól elérhető

Gyakorlati szabály: használja a UITableView-t, ha a képernyő egyszerű sorból álló lista (beállítások, névjegyek, menü). Használja az UICollectionView-t, ha a képernyő rácsot, vízszintes görgetést, körhintát, különböző cellaméreteket vagy összetett csoportosítást igényel. iOS 14-től a UITableView is megkapta a CompositionalLayout támogatását az UICollectionLayoutListConfiguration segítségével, ami lehetővé teszi mindkét komponens előnyeinek kombinálását.

Gyakran ismételt kérdések

Hogyan készítsünk UICollectionView-t vízszintes görgetéssel?

Állítsa be a scrollDirection = .horizontal értéket az UICollectionViewFlowLayout-ban. A CompositionalLayout-hoz használja a NSCollectionLayoutSize elemet fractionalWidth-vel a csoport adaptív szélességéhez. A vízszintes görgetés jó körhintákhoz, galériákhoz és kategóriákhoz. Lapozáshoz állítsa be a collectionView.isPagingEnabled = true értéket, vagy használja az UICollectionViewFlowLayout-ot itemSize = bounds.width értékkel.

Miért nem jeleníti meg az UICollectionView a cellákat?

Ellenőrizze: (1) a cella regisztrálva van-e a register(_:forCellWithReuseIdentifier:) segítségével, (2) a DataSource visszaadja-e az elemek számát > 0, (3) a cella a megfelelő reuseIdentifier-rel lett dequeue-olva, (4) az itemSize nem nulla (FlowLayout esetén). Tipikus hiba — itemSize = CGSize.zero, amelynél a cellák nulla magasságúak. Állítsa be az itemSize-ot explicit módon, vagy implementálja a collectionView(_:layout:sizeForItemAt:) delegáltat.

Hogyan adjunk távolságokat az UICollectionView cellák között?

FlowLayout esetén: layout.minimumInteritemSpacing (elemek között egy sorban) és layout.minimumLineSpacing (sorok között). CompositionalLayout esetén: NSCollectionLayoutGroup.interItemSpacing és contentInsets a csoporton/szakaszon. A sectionInset a szakasz külső távolságait állítja be. Használja a sectionInsetReference = .fromContentInset értéket a Safe Area helyes figyelembevételéhez.

Hogyan frissítsük az UICollectionView-t újratöltés nélkül?

Használja a performBatchUpdates metódust csoportos animációkhoz: collectionView.performBatchUpdates { insertItems, deleteItems, reloadItems }. Biztonságos és animált frissítéshez használja az UICollectionViewDiffableDataSource-t: hívja meg a dataSource.apply(snapshot, animatingDifferences: true) metódust — az összes változás automatikusan kiszámításra és alkalmazásra kerül manuális insert/delete nélkül.

UICollectionView vs CollectionView a SwiftUI-ben?

A SwiftUI-ben az UICollectionView megfelelője a LazyVGrid és a LazyHGrid (iOS 14+). A SwiftUI Grid egyszerűbb írásban (deklaratív szintaxis), de gyengébb teljesítményű az UICollectionView-nál 500+ elem és elrendezés-testreszabás esetén. Összetett gyűjteményekhez használja az UICollectionView-t az UIViewRepresentable segítségével. Az IT Sectr projektjeiben az UICollectionView-t választjuk katalógusokhoz és galériákhoz, a SwiftUI Grid-et egyszerű képernyőkhöz.

Összefoglalás

  • UICollectionView — rugalmas UIKit komponens rácsokhoz, listákhoz, körhintákhoz és egyéni elrendezésekhez (iOS 6+).
  • FlowLayout egyszerű rácsokhoz alkalmas; CompositionalLayout (iOS 13+) összetett, különböző elrendezésű szakaszokhoz.
  • UICollectionViewCell a contentView-t használja az összes subview-hoz — ne adja hozzá őket közvetlenül a cellához.
  • UICollectionViewDiffableDataSource — modern, típusbiztos DataSource automatikus változás-animációval.
  • Egyéni UICollectionViewLayout tetszőleges elrendezések létrehozását teszi lehetővé (kör, spirál, diagram).
  • Az App Store top 100-as listáján lévő iOS-alkalmazások 72%-a használ UICollectionView-t tartalom megjelenítésére.
  • Egyszerű listákhoz használja a UITableView-t; minden máshoz — UICollectionView.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is