UICollectionView iOS के लिए UIKit का एक शक्तिशाली घटक है जो वस्तुओं के संग्रह को ग्रिड, सूचियों और कस्टम लेआउट के रूप में प्रदर्शित करने का प्रबंधन करता है। UITableView के विपरीत, UICollectionView एक कॉलम तक सीमित नहीं है: यह UICollectionViewLayout के माध्यम से मनमानी स्थिति का समर्थन करता है। हम UICollectionView के सार, FlowLayout और CompositionalLayout कैसे काम करते हैं, और Swift में कस्टम सेल कैसे बनाएं, इसके बारे में बताते हैं। IT Sectr में हम UICollectionView का उपयोग गैलरी, कैटलॉग और विज्ञापन बोर्ड के लिए करते हैं। तालिकाओं के साथ तुलना के लिए UITableView के बारे में लेख पढ़ें।
मुख्य बातें
UICollectionView UIKit फ्रेमवर्क का एक वर्ग है जो iOS 6 (2012) में पेश किया गया था। यह UICollectionViewLayout ऑब्जेक्ट द्वारा प्रबंधित एक लचीले लेआउट में कोशिकाओं (UICollectionViewCell) का एक क्रमबद्ध संग्रह प्रदर्शित करता है। UICollectionView UITableView (सूचियाँ) के समान समस्या को हल करता है, लेकिन मनमानी स्थिति के साथ: ग्रिड, कैरोसेल, मोज़ाइक, कैस्केड।
आर्किटेक्चर UICollectionView MVC पैटर्न पर बनाया गया है: डेटा DataSource में, लेआउट UICollectionViewLayout में, व्यवहार UICollectionViewDelegate में। यह पृथक्करण डेटा कोड को बदले बिना लेआउट को बदलने की अनुमति देता है। Apple (WWDC 2025) के अनुसार, App Store के टॉप-100 में से 72% iOS ऐप्स सामग्री प्रदर्शित करने के लिए UICollectionView का उपयोग करते हैं। CollectionView iOS 6 से बहु-स्तंभ लेआउट का समर्थन करता है, और iOS 13 से इसे जटिल अनुभागों के लिए CompositionalLayout मिला।
UICollectionView UITableView के समान पुन: प्रयोज्य कोशिकाओं (reuse queue) का पूल उपयोग करता है। विधि dequeueReusableCell(withReuseIdentifier:for:) पूल से एक सेल लौटाती है या यदि पूल खाली है तो नया बनाती है। UITableView के विपरीत, UICollectionViewCell में एक अंतर्निहित contentView होता है जिसमें आपको सभी सबव्यू जोड़ने चाहिए — उन्हें सीधे सेल में न जोड़ें, क्योंकि contentView सही चयन और संपादन एनीमेशन के लिए जिम्मेदार है।
UICollectionViewFlowLayout — iOS 6 से काम करने वाला मानक लेआउट। यह सेल आकार, स्क्रॉल दिशा, न्यूनतम अंतराल और अनुभागों को कॉन्फ़िगर करने की क्षमता के साथ तत्वों को पंक्तियों (flow) में व्यवस्थित करता है। UICollectionViewCompositionalLayout — आधुनिक लेआउट (iOS 13+) जो ब्लॉकों के संयोजन के माध्यम से लेआउट का वर्णन करता है: समूह → अनुभाग → लेआउट, जहां प्रत्येक समूह क्षैतिज, लंबवत या कस्टम हो सकता है।
| पैरामीटर | UICollectionViewFlowLayout | UICollectionViewCompositionalLayout |
|---|---|---|
| न्यूनतम संस्करण | iOS 6 | iOS 13 |
| जटिल लेआउट | केवल सरल ग्रिड या सूची | विभिन्न लेआउट वाले अनुभाग, समूह, कैरोसेल |
| अनुकूलनशीलता | डेलिगेट आकार के माध्यम से | NSCollectionLayoutDimension.fractionalWidth/Height |
| प्रदर्शन | सभी दृश्य तत्वों को रेंडर करता है | आलसी अनुभाग निर्माण |
| iPad समर्थन | मैन्युअल अनुकूलन की आवश्यकता | fractionalWidth के माध्यम से अनुकूली समूह |
| कार्यान्वयन जटिलता | कम (5–10 पंक्तियाँ) | मध्यम (15–30 पंक्तियाँ) |
// FlowLayout के साथ बुनियादी 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 अनुशंसा (WWDC 2025): नए प्रोजेक्ट के लिए CompositionalLayout का उपयोग करें। यह अनुकूली लेआउट के लिए अधिक क्षमताएं प्रदान करता है, UICollectionView.Representable के माध्यम से UIKit और SwiftUI के साथ बेहतर काम करता है, और ऑटो-आकार के साथ अनुभाग शीर्षलेखों का समर्थन करता है। FlowLayout को समान कोशिकाओं और iOS 12 और उससे नीचे के न्यूनतम संस्करण वाली सरल स्क्रीन के लिए रखें।
UICollectionViewCell — UICollectionView कोशिकाओं के लिए मूल वर्ग। प्रत्येक सेल में contentView (मुख्य कंटेनर), backgroundView (डिफ़ॉल्ट पृष्ठभूमि), selectedBackgroundView (चयनित पृष्ठभूमि) होता है। सेल की उपस्थिति contentView के अंदर कॉन्फ़िगर करें — कभी भी सीधे UICollectionViewCell में सबव्यू न जोड़ें।
// कॉन्फ़िगरेशन के साथ कस्टम सेल
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 बाधाएँ
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 चयन, हाइलाइटिंग, संदर्भ मेनू और पुनर्क्रमण को संभालने के तरीके प्रदान करता है। UITableView के विपरीत, UICollectionViewDelegate न केवल तत्वों पर टैप बल्कि लंबे प्रेस (UIContextMenuInteraction के माध्यम से संदर्भ मेनू) को भी नियंत्रित करने की अनुमति देता है। टैप संभालने के लिए collectionView(_:didSelectItemAt:) लागू करें — यह चयन एनीमेशन पूरा होने पर कॉल किया जाता है।
UICollectionViewDiffableDataSource — iOS 13 में पेश किया गया UICollectionViewDataSource का टाइप-सुरक्षित प्रतिस्थापन। cellForItemAt के माध्यम से मैन्युअल रूप से कोशिकाओं के प्रबंधन के बजाय, DiffableDataSource NSDiffableDataSourceSnapshot का उपयोग करता है — डेटा स्थिति का एक स्नैपशॉट जो स्वचालित रूप से पुरानी और नई स्थिति के बीच अंतर की गणना करता है और परिवर्तनों को एनिमेट करता है।
// अनुभागों के साथ 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)
}
// स्वचालित एनीमेशन के साथ अद्यतन
func updateProducts(_ products: [Product]) {
var snapshot = dataSource.snapshot()
snapshot.deleteItems(snapshot.itemIdentifiers)
snapshot.appendItems(products)
dataSource.apply(snapshot, animatingDifferences: true)
}
}
DiffableDataSource के लाभ: (1) स्वचालित एनीमेशन — insert, delete, reload डिफ़ॉल्ट एनीमेशन के साथ होते हैं; (2) टाइप सुरक्षा — अनुभाग और आइटम टाइप किए गए हैं, रनटाइम क्रैश के बजाय कंपाइल त्रुटियाँ; (3) Snapshot — स्थिति स्नैपशॉट को सहेजा, पूर्ववत, तुलना किया जा सकता है; (4) प्रदर्शन — DiffableDataSource परिवर्तनों के न्यूनतम सेट की गणना करने के लिए Hellier एल्गोरिदम का उपयोग करता है। Apple (WWDC 2024) सभी नए UICollectionView के लिए DiffableDataSource की अनुशंसा करता है, और पुराने DataSource को केवल iOS 12 और पुराने के लिए रखें।
UICollectionViewLayout — एक अमूर्त वर्ग जो संग्रह तत्वों की स्थिति को पूरी तरह से नियंत्रित करता है। यदि FlowLayout और CompositionalLayout उपयुक्त नहीं हैं (उदाहरण के लिए, गोलाकार लेआउट, सर्पिल, आरेख), तो UICollectionViewLayout का उपवर्ग बनाएं और लेआउट तैयारी विधियों को ओवरराइड करें।
// कस्टम गोलाकार लेआउट
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]
}
}
प्रदर्शन: एक कस्टम UICollectionViewLayout को prepare() में विशेषताओं को कैश करना चाहिए और layoutAttributesForItem(at:) में O(1) में वापस करना चाहिए। 1000+ तत्वों वाले संग्रह के लिए, shouldInvalidateLayout(forBoundsChange:) के माध्यम से इंक्रीमेंटल कैश अपडेट का उपयोग करें — यह स्क्रॉल पर पूरे लेआउट की पुनर्गणना से बचाता है। Apple (WWDC 2023) कस्टम लेआउट के बजाय CompositionalLayout की अनुशंसा करता है: यह शुरू से लेआउट लिखने की आवश्यकता के बिना 95% परिदृश्यों को कवर करता है।
UITableView और UICollectionView सूचियाँ प्रदर्शित करने के लिए UIKit के दो मुख्य घटक हैं। UITableView सरल है और एकल-स्तंभ सूचियों के लिए डिज़ाइन किया गया है। UICollectionView अधिक लचीला है और किसी भी लेआउट का समर्थन करता है। उनके बीच चुनाव दृश्य डेटा संरचना और आवश्यक अनुकूलन पर निर्भर करता है।
| पैरामीटर | UITableView | UICollectionView |
|---|---|---|
| लेआउट | केवल लंबवत सूची | सूची, ग्रिड, कैस्केड, कैरोसेल, कस्टम |
| जटिलता | कम (सरल DataSource) | मध्यम (Layout + DataSource + Delegate) |
| डिफ़ॉल्ट सेल | 4 शैलियाँ (basic, subtitle, value1, value2) | केवल खाली (contentView के माध्यम से कस्टम) |
| एडिट मोड | अंतर्निहित (delete, move, insert) | मैन्युअल कार्यान्वयन की आवश्यकता |
| Header/Footer | अंतर्निहित (viewForHeaderInSection) | सप्लीमेंट्री व्यू के माध्यम से |
| प्रदर्शन | सूचियों के लिए उच्च | किसी भी लेआउट के लिए उच्च |
| iOS 6+ | iOS 2 से उपलब्ध | iOS 6 से उपलब्ध |
व्यावहारिक नियम: यदि स्क्रीन पंक्तियों की एक सरल सूची है (सेटिंग्स, संपर्क, मेनू) तो UITableView का उपयोग करें। यदि स्क्रीन को ग्रिड, क्षैतिज स्क्रॉल, कैरोसेल, विभिन्न सेल आकार या जटिल समूहीकरण की आवश्यकता है तो UICollectionView का उपयोग करें। iOS 14 से, UITableView को UICollectionLayoutListConfiguration के माध्यम से CompositionalLayout समर्थन भी मिला, जो दोनों घटकों के लाभों को संयोजित करने की अनुमति देता है।
अक्सर पूछे जाने वाले प्रश्न
UICollectionViewFlowLayout में scrollDirection = .horizontal सेट करें। CompositionalLayout के लिए, अनुकूली समूह चौड़ाई के लिए fractionalWidth के साथ NSCollectionLayoutSize का उपयोग करें। क्षैतिज स्क्रॉल कैरोसेल, गैलरी और श्रेणियों के लिए अच्छा है। पेजिंग के लिए collectionView.isPagingEnabled = true सेट करें या itemSize = bounds.width के साथ UICollectionViewFlowLayout का उपयोग करें।
जाँच करें: (1) सेल register(_:forCellWithReuseIdentifier:) के माध्यम से पंजीकृत है, (2) DataSource आइटम गणना > 0 लौटाता है, (3) सेल सही reuseIdentifier के साथ डीक्यू किया गया है, (4) itemSize शून्य नहीं है (FlowLayout के लिए)। एक सामान्य गलती itemSize = CGSize.zero है, जिससे कोशिकाओं की ऊंचाई शून्य हो जाती है। itemSize स्पष्ट रूप से सेट करें या डेलिगेट collectionView(_:layout:sizeForItemAt:) लागू करें।
FlowLayout के लिए: layout.minimumInteritemSpacing (एक पंक्ति में तत्वों के बीच) और layout.minimumLineSpacing (पंक्तियों के बीच)। CompositionalLayout के लिए: NSCollectionLayoutGroup.interItemSpacing और समूह/अनुभाग पर contentInsets। sectionInset अनुभाग के बाहरी मार्जिन सेट करता है। Safe Area के सही संचालन के लिए sectionInsetReference = .fromContentInset का उपयोग करें।
समूह एनिमेशन के लिए performBatchUpdates का उपयोग करें: collectionView.performBatchUpdates { insertItems, deleteItems, reloadItems }। सुरक्षित और एनिमेटेड अपडेट के लिए, UICollectionViewDiffableDataSource का उपयोग करें: dataSource.apply(snapshot, animatingDifferences: true) कॉल करें — सभी परिवर्तन मैन्युअल insert/delete के बिना स्वचालित रूप से गणना और लागू होंगे।
SwiftUI में, UICollectionView के समकक्ष LazyVGrid और LazyHGrid (iOS 14+) हैं। SwiftUI Grid लिखने में सरल है (घोषणात्मक सिंटैक्स) लेकिन 500+ तत्वों और लेआउट अनुकूलन के लिए प्रदर्शन में UICollectionView से पीछे है। जटिल संग्रह के लिए, UIViewRepresentable के माध्यम से UICollectionView का उपयोग करें। IT Sectr प्रोजेक्ट में, हम कैटलॉग और गैलरी के लिए UICollectionView चुनते हैं, और सरल स्क्रीन के लिए SwiftUI Grid चुनते हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें