UITableView: alapok, listák és cellák iOS alkalmazásokban

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

UITableView — a UIKit fő komponense függőleges listák megjelenítéséhez iOS-ben. A táblázat minden sora egy UITableViewCell cella előre meghatározott stílusokkal. Elmagyarázzuk a UITableView alapjait: DataSource, delegált, cellák újrafelhasználása és táblázatok teljesítménye iOS alkalmazásokban. Az Apple szerint (Human Interface Guidelines, 2026) a UITableView a legtöbbet használt UI komponens iOS-ben — az App Store top-100 alkalmazásának 85%-a tartalmaz legalább egy táblázatot. Komplex elrendezésekhez olvassa el a UICollectionView-ról szóló cikket.

Főbb pontok

  • UITableView — UIKit komponens függőleges listákhoz, elérhető iOS 2.0 (iPhone OS 2) óta.
  • UITableViewCell — táblázatcella négy beépített stílussal és testreszabási lehetőséggel.
  • UITableViewDataSource — protokoll, amely meghatározza a sorok és cellák számát minden szakaszhoz.
  • UITableViewDelegate — protokoll a kijelölés, szerkesztés és sormagasság beállításának kezelésére.
  • UITableViewDiffableDataSource — modern DataSource (iOS 13+) automatikus változásszámítással.

Mi az UITableView iOS-ben?

UITableView — egy osztály a UIKit keretrendszerből, amely görgethető sorlista megjelenítésére szolgál egy oszlopban. Minden sort egy UITableViewCell objektum képvisel. Az UITableView az iPhone OS 2-ben (2008) jelent meg, és azóta is a listák fő komponense iOS-ben. Az UITableView architektúrája az MVC mintára épül: az adatokat a DataSource, a megjelenést és viselkedést a Delegate, a nézetet pedig maga a táblázat kezeli.

Két táblázatstílus: .plain (folyamatos lista opcionális szakaszokkal) és .grouped (csoportosított szakaszok lekerekített sarkokkal és margókkal). iOS 13 óta hozzáadták a .insetGrouped-et — grouped-stílus margókkal a szélektől, amelyet a Beállítások és Egészség alkalmazások használnak. A stílusválasztás befolyásolja az alapértelmezett megjelenést: a plain-táblázatok görgetéskor a szakasz fejlécét a tetejére rögzítik (sticky header), a grouped — nem.

Self-Sizing Cells

iOS 8 óta az UITableView támogatja az automatikus méretű cellákat (self-sizing cells). Az aktiváláshoz állítsa be a tableView.estimatedRowHeight (pl. 80) és a tableView.rowHeight = UITableView.automaticDimension értékeket. A táblázat automatikusan kiszámítja a sor magasságát a cellán belüli Auto Layout korlátozások alapján. A self-sizing csökkenti a teljesítményt összetett cellák esetén — használjon rögzített magasságot (rowHeight) az 500+ elemű táblázatokhoz.

UITableViewCell stílusok: basic, subtitle, value1, value2

UITableViewCell négy beépített stílust kínál, amelyek az esetek 80%-át lefedik anélkül, hogy egyedi cellát kellene létrehozni. Minden stílus a textLabel, detailTextLabel és imageView kombinációjából áll. A stílusválasztás a cella inicializálásakor történik az init(style:reuseIdentifier:) segítségével.

StílustextLabeldetailTextLabelimageViewPélda
.default (.basic)Balra, félkövérNincsOpcionálisMenü, elemek listája
.subtitleBalra, félkövérA textLabel alatt, szürkeOpcionálisNévjegyek, lejátszási listák
.value1Balra, félkövérJobbra, szürkeNincsBeállítások értékekkel
.value2Jobbra, kékBalra, szürkeNincsTelefonkönyv (iOS 6 stílus)
swift
// Táblázat létrehozása egyedi cellákkal
class ContactListController: UIViewController {

    private let tableView = UITableView(frame: .zero, style: .insetGrouped)

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.dataSource = self
        tableView.delegate = self
        tableView.rowHeight = 60
        view.addSubview(tableView)

        // Auto Layout
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    }
}

extension ContactListController: UITableViewDataSource {

    func tableView(_ tableView: UITableView,
                         numberOfRowsInSection section: Int) -> Int {
        contacts.count
    }

    func tableView(_ tableView: UITableView,
                         cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let contact = contacts[indexPath.row]

        var content = cell.defaultContentConfiguration()
        content.text = contact.name
        content.secondaryText = contact.phone
        content.image = UIImage(systemName: "person.circle")
        cell.contentConfiguration = content

        return cell
    }
}

UIContentConfiguration (iOS 14+) — modern módja a cellák konfigurálásának a contentConfiguration segítségével a textLabel/detailTextLabel közvetlen elérése helyett. Használja a cell.defaultContentConfiguration() metódust, vagy hozzon létre egyedi UIContentConfiguration-t. Előnyök: dinamikus típus, sötét téma és VoiceOver támogatás a dobozból. Az Apple (WWDC 2024) a contentConfiguration-t ajánlja minden új UITableView-hez.

DataSource és Delegate: kötelező metódusok

UITableViewDataSource — protokoll, amely adatokat biztosít a táblázat számára. Kötelező metódusok: tableView(_:numberOfRowsInSection:) és tableView(_:cellForRowAt:). Nélkülük a táblázat nem tud egyetlen sort sem megjeleníteni. UITableViewDelegate — protokoll a megjelenés és viselkedés kezelésére: sormagasság, kijelölés, szerkesztés, contextual actions.

swift
// Példa több szakasszal és szerkesztéssel
extension ContactListController: UITableViewDelegate {

    // Egyedi magasság minden sorhoz
    func tableView(_ tableView: UITableView,
                         heightForRowAt indexPath: IndexPath) -> CGFloat {
        80
    }

    // Kijelölés kezelése
    func tableView(_ tableView: UITableView,
                         didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let contact = contacts[indexPath.row]
        showDetail(for: contact)
    }

    // Csúsztatás a törléshez
    func tableView(_ tableView: UITableView,
                         trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath)
        -> UISwipeActionsConfiguration? {
        let deleteAction = UIContextualAction(style: .destructive, title: "Törlés") {
            [weak self] _, _, completion in
            self?.contacts.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            completion(true)
        }
        return UISwipeActionsConfiguration(actions: [deleteAction])
    }
}

Delegate teljesítmény: a méretmetódusok (heightForRowAt) minden látható sorra meghívódnak minden görgetéskor. Egységes magassághoz állítsa be közvetlenül a rowHeight-ot — ez 10-szer gyorsabb, mint a heightForRowAt. A self-sizing cellákhoz állítsa be az estimatedRowHeight és automaticDimension értékeket — a táblázat csak a látható sorokhoz hívja meg a heightForRowAt-ot, a többihez az estimatedRowHeight-t használja.

Cellák újrafelhasználása: reuse queue és register

Reuse queue — újrafelhasználható UITableView cellák készlete. Amikor egy cella elhagyja a képernyőt, nem törlődik, hanem a sorba kerül. Új cellák nem a semmiből jönnek létre — a rendszer meghívja a dequeueReusableCell(withIdentifier:for:) metódust, amely visszaad egy cellát a sorból, vagy újat hoz létre, ha a sor üres. Ez az UITableView teljesítményének kulcsmechanizmusa.

swift
// Egyedi cella gyorsítótárazással
class ContactCell: UITableViewCell {

    private let avatarView = UIImageView()
    private let nameLabel = UILabel()
    private let subtitleLabel = UILabel()

    override init(style: UITableViewCell.Style, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupViews()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupViews() {
        contentView.addSubview(avatarView)
        contentView.addSubview(nameLabel)
        contentView.addSubview(subtitleLabel)

        // Auto Layout korlátozások beállítása
        avatarView.translatesAutoresizingMaskIntoConstraints = false
        // ... korlátozások ...
    }

    func configure(with contact: Contact) {
        nameLabel.text = contact.name
        subtitleLabel.text = contact.phone
        // Avatár aszinkron betöltése
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        avatarView.image = nil
        nameLabel.text = nil
        subtitleLabel.text = nil
    }
}

// Regisztráció és használat
tableView.register(ContactCell.self, forCellReuseIdentifier: "contactCell")

// A cellForRowAt-ban:
let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactCell
cell.configure(with: contacts[indexPath.row])
return cell

prepareForReuse() — metódus, amelyet a cella reuse queue-ba helyezése előtt hívnak meg. Állítsa vissza a cella teljes állapotát: szöveg, képek, animációk, betöltések. A prepareForReuse nélkül egy újrahasznált cella régi adatokat jeleníthet meg: az előző kép egy pillanatra látható lesz, amíg az új be nem töltődik. Az Apple (WWDC 2023) az aszinkron műveletek törlését javasolja a URLSessionTask.cancel() segítségével a prepareForReuse-ben.

Szakaszok, header és footer: adatok csoportosítása

Szakaszok az UITableView-ben logikailag kapcsolódó sorokat csoportosítanak. Minden szakasznak lehet header (fejléc) és footer (lábléc). A szakaszok számát a numberOfSections(in:) metódus határozza meg (alapértelmezett 1). A grouped és insetGrouped stílusoknál a szakaszok vizuálisan el vannak választva margókkal és lekerekített sarkokkal.

DataSource metódusLeírásVisszatérési érték
numberOfSectionsSzakaszok száma (alapértelmezett 1)Int
numberOfRowsInSectionSorok száma a szakaszbanInt
titleForHeaderInSectionSzakasz fejlécének szövegeString?
titleForFooterInSectionSzakasz láblécének szövegeString?
viewForHeaderInSectionEgyedi nézet a header-hezUIView?
heightForHeaderInSectionHeader magasságaCGFloat

Indexelés: a szakaszok közötti gyors navigációhoz adjon hozzá egy indexet — egy karakterlánc-tömböt, amely a jobb oldalon jelenik meg. Implementálja a sectionIndexTitles(for:) metódust — visszaadja az egyes szakaszok első betűinek tömbjét. 26+ szakasz esetén ez kritikusan javítja az UX-et. iOS 15+-ben a táblázatok támogatják a sectionHeaderTopPadding-et — a státuszsor és az első header közötti távolság, amely 0-ra állítható a kompakt elrendezéshez.

UITableView teljesítmény: legjobb gyakorlatok

Teljesítmény Az UITableView kritikus fontosságú a hosszú listákat tartalmazó alkalmazások számára. Fő problémák: lassú görgetés (jank) a nehéz műveletek miatt a cellForRowAt-ban, a heightForRowAt gyakori meghívása, a prefetching hiánya. Az Apple (WWDC 2025) öt kulcsfontosságú gyakorlatot emel ki az 1000+ elemű táblázatokhoz.

  • Flat-height — használjon konstans rowHeight-t a heightForRowAt helyett minden cellához. Különbség: 60 FPS vs 30 FPS egy 500 soros táblázat esetén.
  • Prefetching — implementálja az UITableViewDataSourcePrefetching-et az adatok (képek, API) aszinkron betöltéséhez, mielőtt a cella megjelenik a képernyőn.
  • Kevesebb subview — minden subview a contentView-ben növeli a renderelési időt. Használjon draw()-t egyszerű grafikákhoz (elválasztók, ikonok) a UIImageView helyett.
  • Nehéz műveletek a háttérben — a dátumformázást, lokalizációt, számításokat a modellben végezze, ne a cellForRowAt-ban. Használjon NSCache-t az eredményekhez.
  • DiffableDataSource — cserélje le a reloadData()-t apply(snapshot)-ra — az animáció ingyenesen történik, a táblázat nem töltődik be teljesen újra.
swift
// Optimalizálás prefetchinggel
extension ContactListController: UITableViewDataSourcePrefetching {

    func tableView(_ tableView: UITableView,
                         prefetchRowsAt indexPaths: [IndexPath]) {
        for indexPath in indexPaths {
            let contact = contacts[indexPath.row]
            ImageCache.shared.prefetch(url: contact.avatarUrl)
        }
    }

    func tableView(_ tableView: UITableView,
                         cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
        for indexPath in indexPaths {
            let contact = contacts[indexPath.row]
            ImageCache.shared.cancelPrefetch(url: contact.avatarUrl)
        }
    }
}

// DiffableDataSource használata zökkenőmentes frissítésekhez
class ModernTableController: UIViewController {

    private var dataSource: UITableViewDiffableDataSource<Section, Contact>!

    func applyContacts(_ contacts: [Contact]) {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Contact>()
        snapshot.appendSections([.main])
        snapshot.appendItems(contacts)
        dataSource.apply(snapshot, animatingDifferences: true)
    }
}

Gyakorlati eredmény: ezen optimalizálások alkalmazása 30-ról 60-ra növeli a görgetési FPS-t iPhone 12 és régebbi eszközökön (az Apple tesztek szerint, 2025). Az IT Sectr projektekben a DiffableDataSource-t használjuk minden új táblázathoz, és prefetching-et adunk a képeket tartalmazó táblázatokhoz (avatárok, előnézetek, alkalmazásikonok).

Gyakran ismételt kérdések

Az UITableView nem görget — mit tegyek?

Ellenőrizze: (1) contentSize > frame.size — a táblázatnak több tartalommal kell rendelkeznie, mint a magassága; (2) a táblázat nincs egy másik UIScrollView-n belül, amely elfogja a gesztusokat; (3) isScrollEnabled = true; (4) a numberOfRowsInSection a megfelelő számot adja vissza. Tipikus probléma — egy táblázat heightForRowAt = UITableView.automaticDimension értékkel estimatedRowHeight nélkül, ami végtelen magasságszámításhoz vezet.

Hogyan frissítsem az UITableView-t villogás nélkül?

Használja a performBatchUpdates vagy a DiffableDataSource metódust a reloadData() helyett. A reloadData() teljes újratöltést okoz animáció nélkül, vizuális villogást létrehozva. Pontszerű frissítéshez használja: reloadRows(at:with:), insertRows, deleteRows. A performBatchUpdates-en belüli összes változás egyszerre animálódik. A DiffableDataSource ezt automatikusan teszi kézi hívások nélkül.

Mi a különbség az UITableView és az UICollectionView között?

UITableView — egyoszlopos függőleges lista előre meghatározott cellastílusokkal és beépített szerkesztéssel. UICollectionView — rugalmas elrendezés (rács, lista, körhinta, kaszkád) az elemek tetszőleges elhelyezésével. Válassza az UITableView-t egyszerű listákhoz (beállítások, névjegyek, üzenetek). Válassza az UICollectionView-t galériákhoz, katalógusokhoz, táblákhoz és bármilyen nem lineáris elrendezéshez.

Hogyan távolítsam el az üres sorokat a tartalom alatt az UITableView-ben?

Állítsa be a tableView.tableFooterView = UIView(frame: .zero) értéket. Alapértelmezés szerint az UITableView üres sorokat (elválasztókat) jelenít meg az utolsó elem alatt az alsó széléig. Egy üres UIView beállítása a tableFooterView-ban eltávolítja őket. A grouped-stílushoz ez nem szükséges — a táblázat csak a tényleges sorokat jeleníti meg az utolsó szakasz lekerekített sarkaival.

Hogyan készítsek UITableView-t állandó magassággal?

Állítsa be a tableView.rowHeight = 80 és a tableView.estimatedRowHeight = 0 értékeket, vagy hagyja ki az estimatedRowHeight-t. Rögzített magassággal az UITableView nem hívja meg a heightForRowAt-ot, ami 5–10-szeresére gyorsítja a renderelést a 100+ elemű listáknál. Egyedi magasságú cellákhoz (eltérő tartalom) használjon self-sizing-et: estimatedRowHeight + UITableView.automaticDimension.

Összefoglalás

  • UITableView — a fő UIKit komponens függőleges listákhoz DataSource és Delegate architektúrával.
  • UITableViewCell — 4 beépített stílus (.default, .subtitle, .value1, .value2) és egyedi a contentConfiguration segítségével.
  • Reuse queue — újrafelhasználható cellák készlete; register + dequeueReusableCell + prepareForReuse kötelező.
  • DiffableDataSource (iOS 13+) — típusbiztos DataSource automatikus változásszámítással és animációval.
  • Teljesítmény: rögzített rowHeight, prefetching, kevesebb subview, nehéz műveletek a háttérben.
  • Az iOS top-100 App Store alkalmazások 85%-a UITableView-t használ a tartalom megjelenítéséhez.
  • Rácsokhoz, körhintákhoz és összetett elrendezésekhez használjon UICollectionView-t az UITableView helyett.

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