UITableView: মৌলিক বিষয়, iOS অ্যাপে তালিকা ও সেল

লেখক: IT Sectr প্রকাশিত: 2026-02-23 পড়ার সময়: 9 মিনিট

UITableView — iOS-এ উল্লম্ব তালিকা প্রদর্শনের জন্য UIKit-এর প্রধান উপাদান। টেবিলের প্রতিটি সারি একটি UITableViewCell যা পূর্বনির্ধারিত স্টাইল সহ। আমরা UITableView-এর মৌলিক বিষয় ব্যাখ্যা করছি: DataSource, ডেলিগেট, সেল পুনর্ব্যবহার এবং iOS অ্যাপে টেবিলের কর্মক্ষমতা। Apple (Human Interface Guidelines, 2026) অনুসারে, UITableView iOS-এ সর্বাধিক ব্যবহৃত UI উপাদান হিসেবে রয়ে গেছে — App Store-এর শীর্ষ 100-এ 85% অ্যাপে অন্তত একটি টেবিল থাকে। জটিল লেআউটের জন্য, UICollectionView সম্পর্কে নিবন্ধটি পড়ুন।

মূল পয়েন্ট

  • UITableView — উল্লম্ব তালিকার জন্য UIKit উপাদান, iOS 2.0 (iPhone OS 2) থেকে উপলব্ধ।
  • UITableViewCell — চারটি অন্তর্নির্মিত স্টাইল এবং কাস্টমাইজেশন বিকল্প সহ একটি টেবিল সেল।
  • UITableViewDataSource — একটি প্রোটোকল যা প্রতিটি বিভাগের জন্য সারি এবং সেলের সংখ্যা নির্ধারণ করে।
  • UITableViewDelegate — নির্বাচন, সম্পাদনা এবং সারি উচ্চতা কনফিগারেশনের জন্য প্রোটোকল।
  • UITableViewDiffableDataSource — স্বয়ংক্রিয় পরিবর্তন গণনা সহ আধুনিক DataSource (iOS 13+)।

iOS-এ UITableView কী?

UITableView হল UIKit ফ্রেমওয়ার্কের একটি ক্লাস যা একটি কলামে স্ক্রোলযোগ্য সারির তালিকা প্রদর্শনের জন্য ডিজাইন করা হয়েছে। প্রতিটি সারি একটি UITableViewCell অবজেক্ট দ্বারা উপস্থাপিত হয়। UITableView প্রথম iPhone OS 2 (2008)-এ আবির্ভূত হয় এবং তারপর থেকে iOS-এ তালিকার জন্য প্রধান উপাদান হিসেবে রয়ে গেছে। UITableView-এর আর্কিটেকচার MVC প্যাটার্নের উপর ভিত্তি করে তৈরি: ডেটা DataSource দ্বারা পরিচালিত হয়, চেহারা ও আচরণ Delegate দ্বারা, এবং উপস্থাপনা টেবিল নিজেই করে।

দুটি টেবিল স্টাইল: .plain (ঐচ্ছিক বিভাগ সহ অবিচ্ছিন্ন তালিকা) এবং .grouped (গোলাকার কোণ ও মার্জিন সহ গ্রুপ করা বিভাগ)। iOS 13 .insetGrouped যুক্ত করেছে — প্রান্তে মার্জিন সহ grouped স্টাইল, যা সেটিংস এবং হেলথ অ্যাপে ব্যবহৃত হয়। স্টাইলের পছন্দ ডিফল্ট চেহারাকে প্রভাবিত করে: plain টেবিল স্ক্রোল করার সময় বিভাগ হেডার উপরে আটকে রাখে (স্টিকি হেডার), grouped টেবিল তা করে না।

সেলফ-সাইজিং সেল

iOS 8 থেকে শুরু করে, UITableView সেলফ-সাইজিং সেল সমর্থন করে। সক্ষম করতে, tableView.estimatedRowHeight (যেমন, 80) এবং tableView.rowHeight = UITableView.automaticDimension সেট করুন। টেবিল সেলের ভিতরে Auto Layout কনস্ট্রেইন্টের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে সারির উচ্চতা গণনা করে। জটিল সেলের জন্য সেলফ-সাইজিং কর্মক্ষমতা কমায় — 500+ আইটেমের টেবিলের জন্য স্থির উচ্চতা (rowHeight) ব্যবহার করুন।

UITableViewCell স্টাইল: Basic, Subtitle, Value1, Value2

UITableViewCell চারটি অন্তর্নির্মিত স্টাইল প্রদান করে যা কাস্টম সেল তৈরি না করেই 80% পরিস্থিতি কভার করে। প্রতিটি স্টাইল textLabel, detailTextLabel এবং imageView-এর সংমিশ্রণে গঠিত। init(style:reuseIdentifier:)-এর মাধ্যমে সেল ইনিশিয়ালাইজ করার সময় স্টাইল নির্বাচন করা হয়।

স্টাইলtextLabeldetailTextLabelimageViewউদাহরণ
.default (.basic)বামে, বোল্ডকোনোটি নয়ঐচ্ছিকমেনু, আইটেমের তালিকা
.subtitleবামে, বোল্ডtextLabel-এর নিচে, ধূসরঐচ্ছিককন্টাক্ট, প্লেলিস্ট
.value1বামে, বোল্ডডানে, ধূসরকোনোটি নয়মানসহ সেটিংস
.value2ডানে, নীলবামে, ধূসরকোনোটি নয়ফোন বুক (iOS 6-স্টাইল)
swift
// কাস্টম সেল সহ টেবিল তৈরি করা
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-এ সরাসরি অ্যাক্সেসের পরিবর্তে contentConfiguration-এর মাধ্যমে সেল কনফিগার করার আধুনিক উপায়। cell.defaultContentConfiguration() ব্যবহার করুন বা কাস্টম UIContentConfiguration তৈরি করুন। সুবিধা: ডায়নামিক টাইপ, ডার্ক মোড এবং VoiceOver-এর জন্য অন্তর্নির্মিত সমর্থন। Apple (WWDC 2024) সব নতুন UITableView-এর জন্য contentConfiguration সুপারিশ করে।

DataSource এবং Delegate: বাধ্যতামূলক পদ্ধতি

UITableViewDataSource — একটি প্রোটোকল যা টেবিলের জন্য ডেটা সরবরাহ করে। বাধ্যতামূলক পদ্ধতি: tableView(_:numberOfRowsInSection:) এবং tableView(_:cellForRowAt:)। এগুলা ছাড়া, টেবিল একটি সারিও প্রদর্শন করতে পারে না। UITableViewDelegate — চেহারা ও আচরণ পরিচালনার জন্য প্রোটোকল: সারি উচ্চতা, নির্বাচন, সম্পাদনা, প্রাসঙ্গিক কার্যক্রম।

swift
// একাধিক বিভাগ এবং সম্পাদনা সহ উদাহরণ
extension ContactListController: UITableViewDelegate {

    // প্রতিটি সারির জন্য কাস্টম উচ্চতা
    func tableView(_ tableView: UITableView,
                         heightForRowAt indexPath: IndexPath) -> CGFloat {
        80
    }

    // নির্বাচন পরিচালনা
    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: "মুছুন") {
            [weak self] _, _, completion in
            self?.contacts.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            completion(true)
        }
        return UISwipeActionsConfiguration(actions: [deleteAction])
    }
}

ডেলিগেট কর্মক্ষমতা: আকার পদ্ধতি (heightForRowAt) প্রতিটি স্ক্রোল-এ প্রতিটি দৃশ্যমান সারির জন্য কল করা হয়। একই উচ্চতার জন্য, সরাসরি rowHeight সেট করুন — এটি heightForRowAt-এর চেয়ে 10 গুণ দ্রুত। সেলফ-সাইজিং সেলের জন্য, estimatedRowHeight এবং automaticDimension সেট করুন — টেবিল শুধুমাত্র দৃশ্যমান সারির জন্য heightForRowAt কল করে এবং বাকিগুলোর জন্য estimatedRowHeight ব্যবহার করে।

সেল পুনর্ব্যবহার: পুনর্ব্যবহার সারি এবং রেজিস্টার

পুনর্ব্যবহার সারি — পুনর্ব্যবহারযোগ্য UITableView সেলের একটি পুল। যখন একটি সেল স্ক্রিনের বাইরে স্ক্রোল হয়, তখন তা মুছে ফেলা হয় না বরং সারিতে রাখা হয়। নতুন সেল শূন্য থেকে তৈরি হয় না — সিস্টেম dequeueReusableCell(withIdentifier:for:) কল করে, যা সারি থেকে একটি সেল ফেরত দেয় বা সারি খালি থাকলে নতুন তৈরি করে। এটি UITableView-এর মূল কর্মক্ষমতা প্রক্রিয়া।

swift
// ক্যাশিং সহ কাস্টম সেল
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 কনস্ট্রেইন্ট কনফিগার করা
        avatarView.translatesAutoresizingMaskIntoConstraints = false
        // ... constraints ...
    }

    func configure(with contact: Contact) {
        nameLabel.text = contact.name
        subtitleLabel.text = contact.phone
        // অ্যাসিঙ্ক্রোনাস অবতার লোডিং
    }

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

// নিবন্ধন এবং ব্যবহার
tableView.register(ContactCell.self, forCellReuseIdentifier: "contactCell")

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

prepareForReuse() — একটি পদ্ধতি যা সেলকে পুনর্ব্যবহার সারিতে রাখার আগে কল করা হয়। সমস্ত সেল অবস্থা রিসেট করুন: টেক্সট, ছবি, অ্যানিমেশন, লোডিং অপারেশন। prepareForReuse ছাড়া, পুনর্ব্যবহৃত সেল পুরানো ডেটা দেখাতে পারে: নতুন ছবি লোড না হওয়া পর্যন্ত আগের ছবি এক সেকেন্ডের ভগ্নাংশের জন্য দৃশ্যমান থাকবে। Apple (WWDC 2023) prepareForReuse-এ URLSessionTask.cancel()-এর মাধ্যমে অ্যাসিঙ্ক্রোনাস অপারেশন বাতিল করার সুপারিশ করে।

বিভাগ, হেডার ও ফুটার: ডেটা গ্রুপিং

বিভাগ UITableView-এ যৌক্তিকভাবে সম্পর্কিত সারি গ্রুপ করে। প্রতিটি বিভাগে একটি হেডার এবং ফুটার থাকতে পারে। বিভাগের সংখ্যা numberOfSections(in:) পদ্ধতি দ্বারা নির্ধারিত হয় (ডিফল্ট 1)। grouped এবং insetGrouped স্টাইলের জন্য, বিভাগগুলি মার্জিন এবং গোলাকার কোণ দ্বারা দৃশ্যত পৃথক হয়।

DataSource পদ্ধতিবিবরণরিটার্ন মান
numberOfSectionsবিভাগের সংখ্যা (ডিফল্ট 1)Int
numberOfRowsInSectionএকটি বিভাগে সারির সংখ্যাInt
titleForHeaderInSectionবিভাগ হেডার শিরোনাম টেক্সটString?
titleForFooterInSectionবিভাগ ফুটার শিরোনাম টেক্সটString?
viewForHeaderInSectionহেডারের জন্য কাস্টম ভিউUIView?
heightForHeaderInSectionহেডার উচ্চতাCGFloat

ইনডেক্সিং: বিভাগগুলির মধ্যে দ্রুত নেভিগেশনের জন্য, একটি ইনডেক্স শিরোনাম যুক্ত করুন — ডান পাশে প্রদর্শিত স্ট্রিং-এর একটি অ্যারে। sectionIndexTitles(for:) বাস্তবায়ন করুন — প্রতিটি বিভাগের প্রথম অক্ষরের একটি অ্যারে ফেরত দেয়। 26+ বিভাগের জন্য, এটি UX-কে গুরুত্বপূর্ণভাবে উন্নত করে। iOS 15+-এ, টেবিল sectionHeaderTopPadding সমর্থন করে — স্ট্যাটাস বার এবং প্রথম হেডারের মধ্যে প্যাডিং, যা ঘন লেআউটের জন্য 0-এ রিসেট করা যেতে পারে।

UITableView কর্মক্ষমতা: সর্বোত্তম অভ্যাস

কর্মক্ষমতা দীর্ঘ তালিকা সহ অ্যাপের জন্য UITableView-এর কর্মক্ষমতা গুরুত্বপূর্ণ। সাধারণ সমস্যা: cellForRowAt-এ ভারী অপারেশনের কারণে ধীর স্ক্রোলিং (jank), ঘন ঘন heightForRowAt কল, prefetching-এর অভাব। Apple (WWDC 2025) 1000+ আইটেমের টেবিলের জন্য পাঁচটি মূল অভ্যাস তুলে ধরে।

  • ফ্ল্যাট-উচ্চতা — সমস্ত সেলের জন্য heightForRowAt-এর পরিবর্তে ধ্রুবক rowHeight ব্যবহার করুন। পার্থক্য: 500 সারির টেবিলের জন্য 60 FPS বনাম 30 FPS।
  • Prefetching — সেল স্ক্রিনে appearing আগে অ্যাসিঙ্ক্রোনাস ডেটা লোডিং (ছবি, API) জন্য UITableViewDataSourcePrefetching বাস্তবায়ন করুন।
  • কম সাবভিউ — contentView-এ প্রতিটি সাবভিউ রেন্ডার সময় বাড়ায়। UIImageView-এর পরিবর্তে সাধারণ গ্রাফিক্স (বিভাজক, আইকন) জন্য draw() ব্যবহার করুন।
  • পটভূমিতে ভারী অপারেশন — তারিখ ফরম্যাটিং, স্থানীয়করণ, গণনা মডেলে করা উচিত, cellForRowAt-এ নয়। ফলাফলের জন্য NSCache ব্যবহার করুন।
  • DiffableDataSource — reloadData()-কে apply(snapshot) দিয়ে প্রতিস্থাপন করুন — অ্যানিমেশন বিনামূল্যে ঘটে, টেবিল সম্পূর্ণরূপে রিলোড হয় না।
swift
// Prefetching-এর সাথে অপ্টিমাইজেশন
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 ব্যবহার
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)
    }
}

ব্যবহারিক ফলাফল: এই অপ্টিমাইজেশনগুলি প্রয়োগ করলে iPhone 12 এবং নতুন ডিভাইসে স্ক্রোল FPS 30 থেকে 60-এ বৃদ্ধি পায় (Apple পরীক্ষার ডেটা, 2025 অনুসারে)। IT Sectr প্রকল্পগুলিতে, আমরা সমস্ত নতুন টেবিলের জন্য DiffableDataSource ব্যবহার করি এবং ছবি (অবতার, প্রিভিউ, অ্যাপ আইকন) সহ টেবিলের জন্য prefetching যুক্ত করি।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

UITableView স্ক্রোল হচ্ছে না — কী করবেন?

পরীক্ষা করুন: (1) contentSize > frame.size — টেবিলে তার উচ্চতার চেয়ে বেশি কন্টেন্ট থাকতে হবে; (2) টেবিল অন্য UIScrollView-এর ভিতরে নেই যা জেসচার ইন্টারসেপ্ট করে; (3) isScrollEnabled = true; (4) numberOfRowsInSection সঠিক সংখ্যা ফেরত দেয়। একটি সাধারণ সমস্যা হল estimatedRowHeight ছাড়া heightForRowAt = UITableView.automaticDimension-সহ টেবিল, যা অসীম উচ্চতা গণনার কারণ হয়।

ঝলকানি ছাড়া UITableView কীভাবে আপডেট করবেন?

reloadData()-এর পরিবর্তে performBatchUpdates বা DiffableDataSource ব্যবহার করুন। reloadData() অ্যানিমেশন ছাড়া সম্পূর্ণ রিলোড ঘটায়, যা দৃশ্যত ঝলকানি তৈরি করে। লক্ষ্যযুক্ত আপডেটের জন্য ব্যবহার করুন: reloadRows(at:with:), insertRows, deleteRows। performBatchUpdates-এর ভিতরে সমস্ত পরিবর্তন একসঙ্গে অ্যানিমেট হয়। DiffableDataSource ম্যানুয়াল কল ছাড়াই স্বয়ংক্রিয়ভাবে এটি করে।

UITableView এবং UICollectionView-এর মধ্যে পার্থক্য কী?

UITableView পূর্বনির্ধারিত সেল স্টাইল এবং অন্তর্নির্মিত সম্পাদনা সহ একক-কলাম উল্লম্ব তালিকা। UICollectionView নির্বিচারে উপাদান অবস্থানের সাথে নমনীয় লেআউট (গ্রিড, তালিকা, ক্যারোসেল, ওয়াটারফল)। সাধারণ তালিকার জন্য (সেটিংস, কন্টাক্ট, বার্তা) UITableView বেছে নিন। গ্যালারি, ক্যাটালগ, বোর্ড এবং যেকোনো অ-রৈখিক লেআউটের জন্য UICollectionView বেছে নিন।

UITableView-এ কন্টেন্টের নিচে খালি সারি কীভাবে সরাবেন?

tableView.tableFooterView = UIView(frame: .zero) সেট করুন। ডিফল্টভাবে, UITableView শেষ আইটেমের নিচে খালি সারি (বিভাজক) প্রদর্শন করে। tableFooterView হিসাবে খালি UIView সেট করলে সেগুলি সরে যায়। grouped স্টাইলের জন্য এটি প্রয়োজনীয় নয় — টেবিল শুধুমাত্র শেষ বিভাগে গোলাকার কোণ সহ প্রকৃত সারি প্রদর্শন করে।

স্থির উচ্চতা সহ UITableView কীভাবে তৈরি করবেন?

tableView.rowHeight = 80 এবং tableView.estimatedRowHeight = 0 সেট করুন বা estimatedRowHeight বাদ দিন। স্থির উচ্চতার সাথে, UITableView heightForRowAt কল করে না, যা 100+ আইটেমের তালিকার জন্য রেন্ডারিং 5–10 গুণ দ্রুত করে। কাস্টম উচ্চতা (ভিন্ন কন্টেন্ট) সহ সেলের জন্য, সেলফ-সাইজিং ব্যবহার করুন: estimatedRowHeight + UITableView.automaticDimension।

সারসংক্ষেপ

  • UITableView — DataSource এবং Delegate আর্কিটেকচার সহ উল্লম্ব তালিকার জন্য প্রধান UIKit উপাদান।
  • UITableViewCell — 4টি অন্তর্নির্মিত স্টাইল (.default, .subtitle, .value1, .value2) এবং contentConfiguration-এর মাধ্যমে কাস্টম।
  • পুনর্ব্যবহার সারি — পুনর্ব্যবহারযোগ্য সেলের পুল; register + dequeueReusableCell + prepareForReuse বাধ্যতামূলক।
  • DiffableDataSource (iOS 13+) — স্বয়ংক্রিয় পরিবর্তন গণনা এবং অ্যানিমেশন সহ type-safe DataSource।
  • কর্মক্ষমতা: স্থির rowHeight, prefetching, কম সাবভিউ, পটভূমিতে ভারী অপারেশন।
  • App Store-এর শীর্ষ 100-এ 85% iOS অ্যাপ কন্টেন্ট প্রদর্শনের জন্য UITableView ব্যবহার করে।
  • গ্রিড, ক্যারোসেল এবং জটিল লেআউটের জন্য, UITableView-এর পরিবর্তে UICollectionView ব্যবহার করুন।

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন