In iOS 14, UICollectionView has been enhanced to replace UITableView to some extent. This article looks at how to use it in the form of an example. Note before you study:
- This article still uses the data from the article “iOS 13-Diffabledatasource”.
- Familiarity with basic use of DiffableDataSource is required.
Create UICollectionView
Configure a list-like layout for UICollectionView, and you can also configure a sliding menu.
extension ViewController {
// Create a tabular UICollectionView
func makeCollectionView(a) -> UICollectionView {
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
// Swipe right to delete
config.trailingSwipeActionsConfigurationProvider = { indexPath in
// Find the deleted content
guard let city = self.dataSource.itemIdentifier(for: indexPath) else { return nil }
return UISwipeActionsConfiguration(
actions: [UIContextualAction(
style: .destructive,
title: "Delete",
handler: { [weak self] _._, completion in
// Call delete data
self?.deleteCity(city: city, indexPath: indexPath)
self?.updateList()
completion(true)})])}// Swipe left to add
config.leadingSwipeActionsConfigurationProvider = { indexPath in
return UISwipeActionsConfiguration(
actions: [UIContextualAction(
style: .normal,
title: "Add",
handler: { [weak self] _._, completion in
// Call increment data
self?.addCity(city: City(name: "Wuhu"), indexPath: indexPath)
self?.updateList()
completion(true)})])}// List layout
let layout = UICollectionViewCompositionalLayout.list(using: config)
return UICollectionView(frame: view.frame, collectionViewLayout: layout)
}
}
Copy the code
Add and delete data
extension ViewController {
// Delete data
func deleteCity(city: City.indexPath: IndexPath) {
if indexPath.section = = 0 {
firstCities.remove(at: firstCities.firstIndex(of: city)!)}else {
secondCities.remove(at: secondCities.firstIndex(of: city)!)}}// Add data
func addCity(city: City.indexPath: IndexPath) {
if indexPath.section = = 0 {
firstCities.append(city)
} else {
secondCities.append(city)
}
}
}
Copy the code
Registration of the Cell
Here you can fill in the contents of the Cell just like a UITableView.
extension ViewController {
/ / register Cell
func makeCellRegistration(a) -> UICollectionView.CellRegistration<CityCollectionViewCell.City> {
UICollectionView.CellRegistration { cell, _, city in
// Customize the Cell display
cell.cityLabel.text = city.name
// AccessoryView
cell.accessories = [.disclosureIndicator()]
}
}
}
Copy the code
DiffableDataSource
enum Section: CaseIterable {
case first
case second
}
extension ViewController {
func updateList(a) {
var snapshot = NSDiffableDataSourceSnapshot<Section.City> ()// Add two groups
snapshot.appendSections(Section.allCases)
// Add data to both groups
snapshot.appendItems(firstCities, toSection: .first)
snapshot.appendItems(secondCities, toSection: .second)
dataSource.apply(snapshot)
}
}
Copy the code
Configuring a Data Source
extension ViewController {
// Configure the data source
func makeDataSource(a) -> UICollectionViewDiffableDataSource<Section.City> {
UICollectionViewDiffableDataSource<Section.City>(
collectionView: collectionView,
cellProvider: { view, indexPath, item in
view.dequeueConfiguredReusableCell(
using: self.makeCellRegistration(),
for: indexPath,
item: item
)
}
)
}
}
Copy the code
ViewController
class ViewController: UIViewController {
/ / create UICollectionView
private lazy var collectionView = makeCollectionView()
/ / create the DataSource
private lazy var dataSource = makeDataSource()
let cityNames = ["Beijing"."Nanjing"."Xi 'an"."Hangzhou"."Suzhou"]
/ / the first group
var firstCities: [City] = []
/ / the second group
var secondCities: [City] = []
override func viewDidLoad(a) {
super.viewDidLoad()
for name in cityNames {
firstCities.append(City(name: name))
secondCities.append(City(name: name))
}
// CollectionView
collectionView.dataSource = dataSource
view.addSubview(collectionView)
// Refresh for the first time
updateList()
}
}
Copy the code
The effect
The source code
Lists in UICollectionView case