在 iOS 14 中 UICollectionView 的功能得以继续增强,可以在一定程度上替换 UITableView。本文以一个案例的形式看看如何使用。学习之前需要进行说明:
- 本文依然使用 “iOS 13 - DiffableDataSource” 一文中的数据。
- 需要熟悉 DiffableDataSource 的基本使用。
创建UICollectionView
为 UICollectionView 配置 List 式的布局,还可以配置滑动菜单。
extension ViewController {
// 创建列表式UICollectionView
func makeCollectionView() -> UICollectionView {
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
// 右侧滑动删除
config.trailingSwipeActionsConfigurationProvider = { indexPath in
// 找到删除的内容
guard let city = self.dataSource.itemIdentifier(for: indexPath) else { return nil }
return UISwipeActionsConfiguration(
actions: [UIContextualAction(
style: .destructive,
title: "Delete",
handler: { [weak self] _, _, completion in
// 调用删除数据
self?.deleteCity(city: city, indexPath: indexPath)
self?.updateList()
completion(true)
}
)]
)
}
// 左侧滑动添加
config.leadingSwipeActionsConfigurationProvider = { indexPath in
return UISwipeActionsConfiguration(
actions: [UIContextualAction(
style: .normal,
title: "Add",
handler: { [weak self] _, _, completion in
// 调用增加数据
self?.addCity(city: City(name: "芜湖"), indexPath: indexPath)
self?.updateList()
completion(true)
}
)]
)
}
// 列表布局
let layout = UICollectionViewCompositionalLayout.list(using: config)
return UICollectionView(frame: view.frame, collectionViewLayout: layout)
}
}
增加与删除数据
extension ViewController {
// 删除数据
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)!)
}
}
// 增加数据
func addCity(city: City, indexPath: IndexPath) {
if indexPath.section == 0 {
firstCities.append(city)
} else {
secondCities.append(city)
}
}
}
注册Cell
在这里可以像 UITableView 一样,填充 Cell 的内容。
extension ViewController {
// 注册Cell
func makeCellRegistration() -> UICollectionView.CellRegistration<CityCollectionViewCell, City> {
UICollectionView.CellRegistration { cell, _, city in
// 自定义Cell显示的内容
cell.cityLabel.text = city.name
// AccessoryView
cell.accessories = [.disclosureIndicator()]
}
}
}
DiffableDataSource
enum Section: CaseIterable {
case first
case second
}
extension ViewController {
func updateList() {
var snapshot = NSDiffableDataSourceSnapshot<Section, City>()
// 添加两个分组
snapshot.appendSections(Section.allCases)
// 分别往两个分组添加数据
snapshot.appendItems(firstCities, toSection: .first)
snapshot.appendItems(secondCities, toSection: .second)
dataSource.apply(snapshot)
}
}
配置数据源
extension ViewController {
// 配置数据源
func makeDataSource() -> UICollectionViewDiffableDataSource<Section, City> {
UICollectionViewDiffableDataSource<Section, City>(
collectionView: collectionView,
cellProvider: { view, indexPath, item in
view.dequeueConfiguredReusableCell(
using: self.makeCellRegistration(),
for: indexPath,
item: item
)
}
)
}
}
ViewController
class ViewController: UIViewController {
// 创建UICollectionView
private lazy var collectionView = makeCollectionView()
// 创建DataSource
private lazy var dataSource = makeDataSource()
let cityNames = ["北京", "南京", "西安", "杭州", "苏州"]
// 第一组
var firstCities: [City] = []
// 第二组
var secondCities: [City] = []
override func viewDidLoad() {
super.viewDidLoad()
for name in cityNames {
firstCities.append(City(name: name))
secondCities.append(City(name: name))
}
// CollectionView关联DataSource
collectionView.dataSource = dataSource
view.addSubview(collectionView)
// 第一次进来刷新
updateList()
}
}
网友评论