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 میں iOS ایپس کا 72% مواد ظاہر کرنے کے لیے 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں