UITableView: asoslar, iOS ilovalaridagi ro'yxatlar va hujayralar

Muallif: IT Sectr Nashr etilgan: 2026-02-23 O'qish vaqti: 9 daq

UITableView — iOS da vertikal ro'yxatlarni ko'rsatish uchun UIKit ning asosiy komponenti. Jadvalning har bir qatori oldindan belgilangan uslubdagi UITableViewCell hujayrasidir. UITableView asoslarini tushuntiramiz: DataSource, delegat, hujayralarni qayta ishlatish va iOS ilovalarida jadvallar ishlashi. Apple ma'lumotlariga ko'ra (Human Interface Guidelines, 2026), UITableView iOS da eng ko'p ishlatiladigan UI komponent bo'lib qolmoqda — App Store top-100 ilovalarining 85% kamida bitta jadvalni o'z ichiga oladi. Murakkab maketlar uchun UICollectionView haqidagi maqolani o'qing.

Asosiy fikrlar

  • UITableView — vertikal ro'yxatlar uchun UIKit komponenti, iOS 2.0 dan (iPhone OS 2) mavjud.
  • UITableViewCell — to'rtta o'rnatilgan uslubga ega va sozlash imkoniyati bo'lgan jadval hujayrasi.
  • UITableViewDataSource — har bir bo'lim uchun qator va hujayralar sonini belgilaydigan protokol.
  • UITableViewDelegate — tanlash, tahrirlash va qator balandligini sozlash uchun protokol.
  • UITableViewDiffableDataSource — o'zgarishlarni avtomatik hisoblash bilan zamonaviy DataSource (iOS 13+).

iOS da UITableView nima?

UITableView — bir ustunda aylantiriladigan qatorlar ro'yxatini ko'rsatish uchun UIKit frameworkidagi sinf. Har bir qator UITableViewCell obyekti bilan ifodalanadi. UITableView iPhone OS 2 (2008) da paydo bo'lgan va shu vaqtdan beri iOS da ro'yxatlar uchun asosiy komponent bo'lib qolmoqda. UITableView arxitekturasi MVC naqshiga asoslangan: ma'lumotlar DataSource tomonidan, ko'rinish va xatti-harakat Delegate tomonidan, ko'rinish esa jadvalning o'zi tomonidan boshqariladi.

Ikki jadval uslubi: .plain (ixtiyoriy bo'limlar bilan uzluksiz ro'yxat) va .grouped.insetGrouped qo'shilgan — chekkalardan bo'shliqlar bilan grouped-uslub, Sozlamalar va Salomatlik ilovalarida ishlatiladi. Uslub tanlovi standart ko'rinishga ta'sir qiladi: plain-jadvallar aylantirishda bo'lim headerini yuqoriga yopishtiradi (sticky header), grouped — yopishtirmaydi.

Self-Sizing Cells

iOS 8 dan boshlab, UITableView avtomatik o'lchamli hujayralarni (self-sizing cells) qo'llab-quvvatlaydi. Faollashtirish uchun tableView.estimatedRowHeight (masalan, 80) va tableView.rowHeight = UITableView.automaticDimension ni o'rnating. Jadval hujayra ichidagi Auto Layout cheklovlari asosida qator balandligini avtomatik hisoblaydi. Self-sizing murakkab hujayralar uchun ishlashni pasaytiradi — 500+ elementli jadvallar uchun doimiy balandlikdan (rowHeight) foydalaning.

UITableViewCell uslublari: basic, subtitle, value1, value2

UITableViewCell maxsus hujayra yaratmasdan 80% stsenariylarni qamrab oladigan to'rtta o'rnatilgan uslubni taqdim etadi. Har bir uslub textLabel, detailTextLabel va imageView kombinatsiyasidan iborat. Uslub tanlovi hujayra ishga tushirilganda init(style:reuseIdentifier:) orqali o'rnatiladi.

UslubtextLabeldetailTextLabelimageViewMisol
.default (.basic)Chap, qalinYo'qIxtiyoriyMenyu, elementlar ro'yxati
.subtitleChap, qalintextLabel ostida, kulrangIxtiyoriyKontaktlar, pleylistlar
.value1Chap, qalinO'ng, kulrangYo'qQiymatlar bilan sozlamalar
.value2O'ng, ko'kChap, kulrangYo'qTelefon daftarchasi (iOS 6 uslubi)
swift
// Maxsus hujayralar bilan jadval yaratish
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+) — textLabel/detailTextLabel ga to'g'ridan-to'g'ri murojaat qilish o'rniga contentConfiguration orqali hujayralarni sozlashning zamonaviy usuli. cell.defaultContentConfiguration() dan foydalaning yoki maxsus UIContentConfiguration yarating. Afzalliklari: dinamik tip, qorong'u mavzu va VoiceOver qutidan chiqishi bilan qo'llab-quvvatlanadi. Apple (WWDC 2024) barcha yangi UITableView lar uchun contentConfiguration ni tavsiya qiladi.

DataSource va Delegate: majburiy metodlar

UITableViewDataSource — jadval uchun ma'lumotlarni ta'minlaydigan protokol. Majburiy metodlar: tableView(_:numberOfRowsInSection:) va tableView(_:cellForRowAt:). Ularsiz jadval hech qanday qatorni ko'rsata olmaydi. UITableViewDelegate — ko'rinish va xatti-harakatni boshqarish uchun protokol: qator balandligi, tanlash, tahrirlash, contextual actions.

swift
// Bir nechta bo'lim va tahrirlash bilan misol
extension ContactListController: UITableViewDelegate {

    // Har bir qator uchun maxsus balandlik
    func tableView(_ tableView: UITableView,
                         heightForRowAt indexPath: IndexPath) -> CGFloat {
        80
    }

    // Tanlashni qayta ishlash
    func tableView(_ tableView: UITableView,
                         didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let contact = contacts[indexPath.row]
        showDetail(for: contact)
    }

    // Swipe-to-delete
    func tableView(_ tableView: UITableView,
                         trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath)
        -> UISwipeActionsConfiguration? {
        let deleteAction = UIContextualAction(style: .destructive, title: "O'chirish") {
            [weak self] _, _, completion in
            self?.contacts.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            completion(true)
        }
        return UISwipeActionsConfiguration(actions: [deleteAction])
    }
}

Delegate ishlashi: o'lcham metodlari (heightForRowAt) har bir aylantirishda har bir ko'rinadigan qator uchun chaqiriladi. Teng balandlik uchun to'g'ridan-to'g'ri rowHeight ni o'rnating — bu heightForRowAt dan 10 marta tezroq. Self-sizing hujayralari uchun estimatedRowHeight va automaticDimension ni o'rnating — jadval heightForRowAt ni faqat ko'rinadigan qatorlar uchun chaqiradi, qolganlari uchun estimatedRowHeight dan foydalanadi.

Hujayralarni qayta ishlatish: reuse queue va register

Reuse queue — qayta ishlatiladigan UITableView hujayralari havzasi. Hujayra ekranni tark etganda, o'chirilmaydi, balki navbatga qo'yiladi. Yangi hujayralar noldan yaratilmaydi — tizim dequeueReusableCell(withIdentifier:for:) ni chaqiradi, u navbatdan hujayra qaytaradi yoki navbat bo'sh bo'lsa yangisini yaratadi. Bu UITableView ishlashining asosiy mexanizmidir.

swift
// Keshlash bilan maxsus hujayra
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 cheklovlarini sozlash
        avatarView.translatesAutoresizingMaskIntoConstraints = false
        // ... cheklovlar ...
    }

    func configure(with contact: Contact) {
        nameLabel.text = contact.name
        subtitleLabel.text = contact.phone
        // Avatarni asinxron yuklash
    }

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

// Ro'yxatdan o'tkazish va foydalanish
tableView.register(ContactCell.self, forCellReuseIdentifier: "contactCell")

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

prepareForReuse() — hujayra reuse queue ga qo'yilishidan oldin chaqiriladigan metod. Hujayraning barcha holatini tiklang: matn, tasvirlar, animatsiyalar, yuklamalar. prepareForReuse bo'lmasa, qayta ishlatilgan hujayra eski ma'lumotlarni ko'rsatishi mumkin: oldingi tasvir yangisi yuklanmaguncha soniyaning bir qismi ko'rinadi. Apple (WWDC 2023) prepareForReuse da URLSessionTask.cancel() orqali asinxron operatsiyalarni tozalashni tavsiya qiladi.

Bo'limlar, header va footer: ma'lumotlarni guruhlash

Bo'limlar UITableView da mantiqiy bog'langan qatorlarni guruhlaydi. Har bir bo'lim header (sarlavha) va footer (pastki) ga ega bo'lishi mumkin. Bo'limlar soni numberOfSections(in:) metodi bilan aniqlanadi (standart 1). Grouped va insetGrouped uslublari uchun bo'limlar vizual ravishda bo'shliqlar va yumaloq burchaklar bilan ajratiladi.

DataSource metodiTavsifQaytariladigan qiymat
numberOfSectionsBo'limlar soni (standart 1)Int
numberOfRowsInSectionBo'limdagi qatorlar soniInt
titleForHeaderInSectionBo'lim sarlavhasi matniString?
titleForFooterInSectionBo'lim pastki matniString?
viewForHeaderInSectionHeader uchun maxsus ko'rinishUIView?
heightForHeaderInSectionHeader balandligiCGFloat

Indekslash: bo'limlar bo'ylab tez navigatsiya uchun indeks qo'shing — o'ng tomonda ko'rsatiladigan satrlar massivi. sectionIndexTitles(for:) ni amalga oshiring — har bir bo'limning birinchi harflaridan iborat massivni qaytaradi. 26+ bo'lim uchun bu UX ni keskin yaxshilaydi. iOS 15+ da jadvallar sectionHeaderTopPadding ni qo'llab-quvvatlaydi — status bar va birinchi header o'rtasidagi zich maket uchun 0 ga tushirilishi mumkin bo'lgan bo'shliq.

UITableView ishlashi: eng yaxshi amaliyotlar

Ishlash UITableView uzoq ro'yxatli ilovalar uchun juda muhimdir. Asosiy muammolar: cellForRowAt dagi og'ir operatsiyalar tufayli sekin aylantirish (jank), heightForRowAt ning tez-tez chaqirilishi, prefetching ning yo'qligi. Apple (WWDC 2025) 1000+ elementli jadvallar uchun beshta asosiy amaliyotni ta'kidlaydi.

  • Flat-height — barcha hujayralar uchun heightForRowAt o'rniga doimiy rowHeight dan foydalaning. Farq: 500 qatorli jadval uchun 60 FPS vs 30 FPS.
  • Prefetching — hujayra ekranda paydo bo'lishidan oldin ma'lumotlarni (tasvirlar, API) asinxron yuklash uchun UITableViewDataSourcePrefetching ni amalga oshiring.
  • Kamroq subview — contentView dagi har bir subview render vaqtini oshiradi. UIImageView o'rniga oddiy grafikalar (ajratgichlar, belgilar) uchun draw() dan foydalaning.
  • Og'ir operatsiyalarni fonda bajaring — sana formatlash, lokalizatsiya, hisoblashlarni modelda bajaring, cellForRowAt da emas. Natijalar uchun NSCache dan foydalaning.
  • DiffableDataSource — reloadData() ni apply(snapshot) bilan almashtiring — animatsiya bepul sodir bo'ladi, jadval to'liq qayta yuklanmaydi.
swift
// Prefetching bilan optimallashtirish
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)
        }
    }
}

// Silliq yangilanishlar uchun DiffableDataSource dan foydalanish
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)
    }
}

Amaliy natija: ushbu optimallashtirishlarni qo'llash iPhone 12 va undan eski qurilmalarda aylantirish FPS ni 30 dan 60 ga oshiradi (Apple testlariga ko'ra, 2025). IT Sectr loyihalarida barcha yangi jadvallar uchun DiffableDataSource dan foydalanamiz va tasvirlar (avatarlar, oldindan ko'rish, ilova belgilari) bo'lgan jadvallarga prefetching qo'shamiz.

Tez-tez beriladigan savollar

UITableView aylanmayapti — nima qilish kerak?

Tekshiring: (1) contentSize > frame.size — jadval balandligidan ko'proq tarkibga ega bo'lishi kerak; (2) jadval imo-ishoralarni ushlab qoladigan boshqa UIScrollView ichida emas; (3) isScrollEnabled = true; (4) numberOfRowsInSection to'g'ri sonni qaytaradi. Odatiy muammo — estimatedRowHeight holda heightForRowAt = UITableView.automaticDimension, bu cheksiz balandlik hisoblashiga olib keladi.

UITableView ni miltillamasdan qanday yangilash mumkin?

reloadData() o'rniga performBatchUpdates yoki DiffableDataSource dan foydalaning. reloadData() animatsiyasiz to'liq qayta yuklashni keltirib chiqaradi, vizual miltillashni yaratadi. Nuqtali yangilash uchun foydalaning: reloadRows(at:with:), insertRows, deleteRows. performBatchUpdates ichidagi barcha o'zgarishlar bir vaqtda animatsiya qilinadi. DiffableDataSource buni qo'lda chaqiruvlarsiz avtomatik qiladi.

UITableView va UICollectionView o'rtasidagi farq nima?

UITableView — oldindan belgilangan hujayra uslublari va o'rnatilgan tahrirlash bilan bir ustunli vertikal ro'yxat. UICollectionView — elementlarning ixtiyoriy joylashuvi bilan moslashuvchan maket (grid, ro'yxat, karusel, kaskad). Oddiy ro'yxatlar uchun UITableView ni tanlang (sozlamalar, kontaktlar, xabarlar). Galereyalar, kataloglar, doskalar va har qanday chiziqli bo'lmagan maketlar uchun UICollectionView ni tanlang.

UITableView da tarkib ostidagi bo'sh qatorlarni qanday olib tashlash mumkin?

tableView.tableFooterView = UIView(frame: .zero) ni o'rnating. Standart bo'yicha, UITableView oxirgi elementdan pastki chetigacha bo'sh qatorlarni (ajratgichlarni) ko'rsatadi. tableFooterView da bo'sh UIView o'rnatish ularni olib tashlaydi. Grouped-uslub uchun bu talab qilinmaydi — jadval faqat oxirgi bo'limning yumaloq burchaklari bilan haqiqiy qatorlarni ko'rsatadi.

Doimiy balandlikdagi UITableView ni qanday yaratish mumkin?

tableView.rowHeight = 80 va tableView.estimatedRowHeight = 0 ni o'rnating yoki estimatedRowHeight ni tashlab keting. Doimiy balandlik bilan UITableView heightForRowAt ni chaqirmaydi, bu 100+ elementli ro'yxatlar uchun renderlashni 5–10 marta tezlashtiradi. Maxsus balandlikdagi hujayralar (turli tarkib) uchun self-sizing dan foydalaning: estimatedRowHeight + UITableView.automaticDimension.

Xulosa

  • UITableView — DataSource va Delegate arxitekturasi bilan vertikal ro'yxatlar uchun asosiy UIKit komponenti.
  • UITableViewCell — 4 o'rnatilgan uslub (.default, .subtitle, .value1, .value2) va contentConfiguration orqali maxsus hujayralar.
  • Reuse queue — qayta ishlatiladigan hujayralar havzasi; register + dequeueReusableCell + prepareForReuse majburiy.
  • DiffableDataSource (iOS 13+) — avtomatik o'zgarishlarni hisoblash va animatsiya bilan tip-xavfsiz DataSource.
  • Ishlash: doimiy rowHeight, prefetching, kamroq subview, og'ir operatsiyalar fonda.
  • App Store top-100 iOS ilovalarining 85% tarkibni ko'rsatish uchun UITableView dan foydalanadi.
  • Gridlar, karusellar va murakkab maketlar uchun UITableView o'rniga UICollectionView dan foydalaning.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing