当前位置:网站首页>Introduction to uicollectionviewdiffabledatasource and nsdiffabledatasourcesnapshot
Introduction to uicollectionviewdiffabledatasource and nsdiffabledatasourcesnapshot
2022-06-28 05:36:00 【Daniel_ Coder】
1. Preface
stay iOS13 After coming out , Apple pairs UICollectionView Of API Updated , Launched UICollectionViewDiffableDataSource agreement , Let's take a look at this agreement .
2. UICollectionViewDiffableDataSource Use
Before use , Let's first look at its definition .
@MainActor class UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType> : NSObject where SectionIdentifierType : Hashable, ItemIdentifierType : HashableDiffableDataSource Object is a UICollectionView Special data source types for object collaboration . It provides a simple 、 Manage in an effective way UICollectionView Data and UI Update the desired behavior . It also meets UICollectionViewDataSource agreement , And provide implementation for all methods of the protocol .
So how do they work ? It is mainly divided into 4 Step :
- take dataSource And CollectionView Association .
- Achieve one Cell To configure CollectionView Of Cell.
- Generate the current data to be displayed .
- Display the data in UI On .
Creating UICollectionViewDiffableDataSource When the object , We need to pass in one collectionview object , This collectionview Objects will be associated with diffableDataSource Object association . Also pass in a closure (CellProvider), To configure each... We want to display cell.
Let's first look at the initialization method :
public init(collectionView: UICollectionView, cellProvider: @escaping UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.CellProvider)
public typealias CellProvider = (_ collectionView: UICollectionView, _ indexPath: IndexPath, _ itemIdentifier: ItemIdentifierType) -> UICollectionViewCell?The method is implemented as follows :
// establish dataSource, And configuration CellProvider.
dataSource = UICollectionViewDiffableDataSource<Int, UUID>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, itemIdentifier: UUID) -> UICollectionViewCell? in
// Configure and return cell.
}Of course! , The above generics need to be determined according to the types used in the actual project .
When created diffableDataSource, The implementation is configured Cell The closure of , The next step is to show the data , At this time, we need to use a thing called snapshot (NSDiffableDataSourceSnapshot),App The data to be displayed in will basically change over time , For example, to show the video interface , And the data at a certain point in time , It can be called the current state of the data State,NSDiffableDataSourceSnapshot Capture the current data state , And in UI Displayed on the . The next section will be on NSDiffableDataSourceSnapshot For further explanation .
For now, post the last two of the above four steps , So as not to be incomplete .
// Create a snapshot.
var snapshot = NSDiffableDataSourceSnapshot<Int, UUID>()
// to snapshot Add current data .
snapshot.appendSections([0])
snapshot.appendItems([UUID(), UUID(), UUID()])
// call dataSource Of apply Method to display data
dataSource.apply(snapshot, animatingDifferences: true)After a few steps above , The data can be displayed , Successful use UICollectionViewDiffableDataSource Replaced UICollectionViewDataSource agreement , There is no need to implement UICollectionViewDataSource There are several in the agreement section, Every section There are several item, as well as cellforitem Methods .
UICollectionViewDiffableDataSource Commonly used Method :
1. UICollectionViewDiffableDataSource Initialization method , When initializing, you need to pass in a UICollectionView Object is bound to it , Colleagues also bring one CellProvider Closure , Configure in this closure cell.
init(collectionView: UICollectionView, cellProvider: UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.CellProvider)2. CellProvider Closure , Used to configure cell, amount to UICollectionViewDataSource Inside cellForItem Method .
typealias UICollectionViewDiffableDataSource.CellProvider
// The definition is as follows :
typealias UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.CellProvider = (_ collectionView: UICollectionView, _ indexPath: IndexPath, _ itemIdentifier: ItemIdentifierType) -> UICollectionViewCell?The closure takes three parameters ,collectionView、indexPath as well as itemIdentifier, And ask to return a cell.
Examples are as follows :
let cellRegistration = UICollectionView.CellRegistration<TextCell, Int> { (cell, indexPath, identifier) in
// Populate the cell with our item description.
cell.label.text = "\(identifier)"
cell.contentView.backgroundColor = .cornflowerBlue
cell.label.textAlignment = .center
cell.label.font = UIFont.preferredFont(forTextStyle: .title1)
}
dataSource = UICollectionViewDiffableDataSource<Section, Int>(collectionView: collectionView) { (collectionView: UICollectionView, indexPath: IndexPath, identifier: Int) -> UICollectionViewCell? in
// Return the cell.
return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: identifier)
}3. Set up Section header and Footer Of supplementaryViewProvider Method Closure
typealias UICollectionViewDiffableDataSource.SupplementaryViewProvider
var supplementaryViewProvider: UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.SupplementaryViewProvider?SupplementaryViewProvider The definition is as follows :
typealias UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.SupplementaryViewProvider = (_ collectionView: UICollectionView, _ elementKind: String, _ indexPath: IndexPath) -> UICollectionReusableView?The closure takes three parameters ,collectionView、kind as well as indexPath, And ask to return a UICollectionReusableView.kind Just give header perhaps footer A sign of .
Take a look at the sample code :
let headerRegistration = UICollectionView.SupplementaryRegistration<TitleSupplementaryView>(elementKind: "SectionHeader") { (supplementaryView, string, indexPath) in
supplementaryView.label.text = "\(string) for section \(indexPath.section)"
supplementaryView.backgroundColor = .lightGray
supplementaryView.layer.borderColor = UIColor.black.cgColor
supplementaryView.layer.borderWidth = 1.0
}
let footerRegistration = UICollectionView.SupplementaryRegistration<TitleSupplementaryView>(elementKind: "SectionFooter") { (supplementaryView, string, indexPath) in
supplementaryView.label.text = "\(string) for section \(indexPath.section)"
supplementaryView.backgroundColor = .lightGray
supplementaryView.layer.borderColor = UIColor.black.cgColor
supplementaryView.layer.borderWidth = 1.0
}
dataSource.supplementaryViewProvider = { (view, kind, index) in
return self.collectionView.dequeueConfiguredReusableSupplementary(using: kind == "SectionHeader" ? headerRegistration : footerRegistration, for: index)
}4. according to indexPath Returns the specified Item object .
func itemIdentifier(for: IndexPath) -> ItemIdentifierType?
5. according to Item Object returns its indexPath.
func indexPath(for: ItemIdentifierType) -> IndexPath?6. Returns the of the specified index location Section.
func sectionIdentifier(for: Int) -> SectionIdentifierType?
7. return Section Index location Int.
func index(for: SectionIdentifierType) -> Int?
8. Get current CollectionView Displayed snapshot data .
func snapshot() -> NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>9. Use the current snapshot to update UI.
// Update the current snapshot To Collectionview On , And decide whether to bring animation .
func apply(NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool)
// Update the current snapshot To Collectionview On , After the update is completed, there will be a completion callback .
func apply(NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool, completion: (() -> Void)?)10. Get specified Section What is shown items.
func snapshot(for: SectionIdentifierType) -> NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>11. Updates the specified Section Of items.
// Updates the specified Section Of items, And decide whether there is animation , And update completion callback .
func apply(NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>, to: SectionIdentifierType, animatingDifferences: Bool, completion: (() -> Void)?)
// Updates the specified Section Of items, And decide whether there is animation .
func apply(NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>, to: SectionIdentifierType, animatingDifferences: Bool)3. NSDiffableDataSourceSnapshot Use
A representation of the state of the data in a view at a specific point in time.
in other words NSDiffableDataSourceSnapshot Used to display the status of data at a certain time .
struct NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> where SectionIdentifierType : Hashable, ItemIdentifierType : HashableBy definition ,NSDiffableDataSourceSnapshot from Sections and items form , And it can be displayed in the order we want , We can also increase 、 Delete and move section and item To configure the displayed content .
Special attention is paid to : every last section and item We need to comply with Hashable agreement , Must have a unique identifier , It can be used Swift In the value type struct and enum, Includes some built-in types , such as :Int、String、UUID etc. , If you use Swift Class As identifier , Then the Class It has to be for NSObject Subclasses of .
As written in the code above , use NSDiffableDataSourceSnapshot Display the data , The first step is to create NSDiffableDataSourceSnapshot object , And add data , The second step ,dataSource call apply Method to display data .
In addition to creating an empty Snapshot, It can also be done through dataSource Of snapshot() Method to get the current snapshot object , And then modify the data , Last apply Show .
So let's see NSDiffableDataSourceSnapshot Related methods :
NSDiffableDataSourceSnapshot Commonly used Method :
1. Initialization method , Create an empty Snapshot:
init()
2. Add... With unique identifier Section data , Need to pass a Section Array :
func appendSections([SectionIdentifierType])3. To... With a unique identifier Section Add... With unique identifier Item data , If only one Section,toSection Parameters can not be passed , If it is more Section data structure , Traverse Sections Add data Items Can be .
func appendItems([ItemIdentifierType], toSection: SectionIdentifierType?)4. Get current snapshot Next Item Number
var numberOfItems: Int
5. Get current snapshot Next Section Number
var numberOfSections: Int
6. Get current snapshot Let's designate Section Of Item Number
func numberOfItems(inSection: SectionIdentifierType) -> Int
7. Get current snapshot All of them Item An array of objects
var itemIdentifiers: [ItemIdentifierType]
8. Get current snapshot All of them Section An array of objects
var sectionIdentifiers: [SectionIdentifierType]
9. At present snapshot Next , According to the specified Item, Get the Item The index of .
func indexOfItem(ItemIdentifierType) -> Int?
10. At present snapshot Next , According to the specified Section, Get the Section The index of .
func indexOfSection(SectionIdentifierType) -> Int?
11. At present snapshot Next , According to the specified Section, Get all under it Items.
func itemIdentifiers(inSection: SectionIdentifierType) -> [ItemIdentifierType]12. At present snapshot Next , Get specified Item Where Section.
func sectionIdentifier(containingItem: ItemIdentifierType) -> SectionIdentifierType?3.2 Insert Sections and Items Method :
1. In the specified Item Insert... At the back Items Array
func insertItems([ItemIdentifierType], afterItem: ItemIdentifierType)2. In the specified Item Insert in front Items Array
func insertItems([ItemIdentifierType], beforeItem: ItemIdentifierType)3. At the designated Section Insert... At the back Section Array
func insertSections([SectionIdentifierType], afterSection: SectionIdentifierType)4. At the designated Section Insert in front Section Array
func insertSections([SectionIdentifierType], beforeSection: SectionIdentifierType)3.3 remove Sections and Items Method
1. From the current snapshot Remove all Items
func insertSections([SectionIdentifierType], beforeSection: SectionIdentifierType)2. From the current snapshot Remove the specified Items
func deleteItems([ItemIdentifierType])
3. From the present snapshot Remove the specified Sections
func deleteSections([SectionIdentifierType])
3.4 Re Sections and Items Sorting method
1. Specifies the Item Move from the current position to a Item Rear position of
func moveItem(ItemIdentifierType, afterItem: ItemIdentifierType)
2. Specifies the Item Move from the current position to a Item Front position of
func moveItem(ItemIdentifierType, beforeItem: ItemIdentifierType)3. Specifies the Section Move from the current position to a Section Rear position of
func moveSection(SectionIdentifierType, afterSection: SectionIdentifierType)4. Specifies the Section Move from the current position to a Section Front position of
func moveSection(SectionIdentifierType, beforeSection: SectionIdentifierType)3.5 Refresh method
1. Reload snapshot It is specified in Items.
func reloadItems([ItemIdentifierType])
2. Update current snapshot The specified Items, And keep the existing cell.
func reconfigureItems([ItemIdentifierType])
The method in iOS15、iPadOS15、tvOS15、Xcode13 And later methods , And reloadItems(_:) The difference is , This method preserves the existing cell, to update cell According to the content , If you want better performance , So use reconfigureItems(_:) Better .
CellProvider The closure must be the provided indexPath dequeue Of the same type cell, And must be given indexPath Returns the same existing cell. because reconfigureItems(_:) This method will reconfigure the existing cell, therefore UICollectionView Not for each dequeue Of cell call prepareForReuse. If indexPath Return different types of cell, Please use reloadItems(_:) Instead of .
Personally, I think the popular point is the same type cell Change the data , use reconfigureItems(_:) Method , If you change data of different data types , And cell The style is different , Then use reloadItems(_:)
3. return snapshot After the update , Reconfigured Items.(iOS15+、iPadOS15+、tvOS15+、Xcode13+)
var reconfiguredItemIdentifiers: [ItemIdentifierType]
4. return snapshot After the update , Updated Items.(iOS15+、iPadOS15+、tvOS15+、Xcode13+)
var reloadedItemIdentifiers: [ItemIdentifierType]
5. Updates the specified Section The data of
func reloadSections([SectionIdentifierType])
6. return snapshot After the update , Updated Sections.(iOS15+、iPadOS15+、tvOS15+、Xcode13+)
var reloadedSectionIdentifiers: [SectionIdentifierType]
summary
This article mainly introduces how to use UICollectionViewDiffableDataSource and NSDiffableDataSourceSnapshot To replace UICollectionViewDataSource complete UICollectionView The filling of the data aspect of .
The article is relatively simple , And many colleagues have posted similar blogs , But a good memory is not as good as a bad pen , recorded , I learned by myself , Also hope to help others .
If you like it, just like it or pay attention to it !!!
边栏推荐
- CpG solid support research: lumiprobe general CpG type II
- Animation de ligne
- mysql 导出查询结果成 excel 文件
- jq图片放大器
- Keil C51的Data Overlaying机制导致的函数重入问题
- Programmer - Shepherd
- [C language practice - printing hollow square and its deformation]
- MySQL 45讲 | 05 深入浅出索引(下)
- 【MYSQL】所有查询表中有2千万数据--sql如何优化
- [leetcode] 12. Integer to Roman numeral
猜你喜欢

Voltage mode and current mode control of switching power supply

jsp连接Oracle实现登录注册

What does mysql---where 1=1 mean

阴阳师页面

Mysql-16-subquery

电子邮件营销的优势在哪里?为什么shopline独立站卖家如此重视?

Detailed usage configuration of the shutter textbutton, overview of the shutter buttonstyle style and Practice
![[Linux] - using xshell to install MySQL on Linux and realize the deployment of webapp](/img/07/e044a6ef14a6576dbee1c6a009ab4f.png)
[Linux] - using xshell to install MySQL on Linux and realize the deployment of webapp

一看就会 MotionLayout使用的几种方式

Lhasa accordion
随机推荐
阴阳师页面
拉萨手风琴
Line animation
【无标题】drv8825步进电机驱动板子原理图
Bidirectional level conversion circuit
Mysql-16-subquery
Store inventory management system source code
【C语言练习——打印空心正方形及其变形】
Why don't big manufacturers use undefined
博客登录框
Study on modified triphosphate: lumiprobe amino-11-ddutp
Animation de ligne
[leetcode] 12. Integer to Roman numeral
Keil C51的Data Overlaying机制导致的函数重入问题
Zzuli:1072 frog climbing well
数据中台:数据治理的七把利剑
数据仓库:DWS层设计原则
TypeScript基础类型
Can wechat applets import the data in the cloud development database into makers with one click in the map component
File foundation - read / write, storage