collection view list cell 添加/删除cell时,如何更新cell的indexPath?
collection view list cell when the cell is added / deleted, how to update the indexPath of the cell?
我正在处理集合视图列表单元格,我想知道在 iOS14 上使用可比较数据源和快照时如何更新 indexPath。
在我的ViewController的viewdidload中,我调用了注册单元信息的configureDataSource方法。另外,我有一个 displayEvents 方法,它从后端获取事件数据并将它们显示在集合视图单元格上。 eventDataSource 包含一个事件数组,因此当获取事件数据时,它会更新数组以便 ViewController 可以显示数据。
我还有一个从 EventActionModalViewController 调用的 addEvent 函数,就像用户键入事件名称并发送 .save API 请求以将数据存储在数据库中一样。它工作正常,我的意思是成功添加数据后端并在集合视图列表中显示新事件。但是,问题是集合视图的 indexPath 没有更新。
例如,如果集合视图中已经有两个事件,则它们的indexPath 为[0,0] and [0,1]
。 (我在 print("here is the indexPath: \(indexPath)")
中将它们打印出来)
而我添加新事件后,collection view上有3个事件,是正确的,但是indexPath变成了[0,0],[0,0] and [0,1]
。所以我认为已经显示的事件的 indexPath 没有更新。应用快照不足以更新每个单元格的 indexPath 吗?我在想即使在应用快照之后,它仍然需要重新加载集合视图以将新的 indexPath 应用到单元格,或类似的东西。
有人遇到过同样的问题吗?如果是这样,您如何将新的 indexPath 应用于单元格?
我还有一个删除单元格的功能,但它也不会更新 indexPath。
顺便说一句,我正在开发 iOS14 的应用程序,所以不能将一个应用程序用于 iOS15...
private var eventDataSource = EventDataSource()
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView() // -> create collection view and set constraints
configureDataSource()
displayEvents()
}
func configureDataSource() {
let cellRegistration = UICollectionView.CellRegistration<ListCell, Event> { cell, indexPath, Event in
cell.Event = Event
let moreAction = UIAction(image: Images.setting) { _ in
let vc = EventActionModalViewController();
vc.modalPresentationStyle = .overCurrentContext
print("here is the indexPath: \(indexPath)")
vc.indexPath = indexPath
self.tabBarController?.present(vc, animated: false, completion: nil)
}
let moreActionButton = UIButton(primaryAction: moreAction)
moreActionButton.tintColor = UIColor.ouchienLightGray()
let moreActionAccessory = UICellAccessory.CustomViewConfiguration(
customView: moreActionButton,
placement: .trailing(displayed: .whenEditing, at: { _ in return 0 })
)
cell.accessories = [
.customView(configuration: moreActionAccessory),
.disclosureIndicator(displayed: .whenNotEditing, options: .init(tintColor: .systemGray))
]
}
dataSource = UICollectionViewDiffableDataSource<Section, Event>(collectionView: collectionView) {
(collectionView, indexPath, Event) -> UICollectionViewCell? in
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: Event)
return cell
}
}
func displayEvents() {
eventDataSource.fetchEvents { [weak self] in
self?.applySnapshot(animatingDifferences: true)
}
}
func addEvent(EventTitle: String) {
eventDataSource.save(eventTitle: EventTitle, completion: { [weak self] in
self?.applySnapshot(animatingDifferences: true)
})
}
func applySnapshot(animatingDifferences: Bool = true) {
snapshot = NSDiffableDataSourceSnapshot<Section, Event>()
snapshot.appendSections([.List])
snapshot.appendItems(eventDataSource.Events)
dataSource?.apply(snapshot, animatingDifferences: animatingDifferences)
}
您在 moreAction
中传递的索引路径是在单元格注册时捕获的索引路径,只有在创建单元格时才会发生这种情况,但不会回收。
您需要随时调用UICollectionView.indexPathForCell
获取正确的索引。
我正在处理集合视图列表单元格,我想知道在 iOS14 上使用可比较数据源和快照时如何更新 indexPath。
在我的ViewController的viewdidload中,我调用了注册单元信息的configureDataSource方法。另外,我有一个 displayEvents 方法,它从后端获取事件数据并将它们显示在集合视图单元格上。 eventDataSource 包含一个事件数组,因此当获取事件数据时,它会更新数组以便 ViewController 可以显示数据。
我还有一个从 EventActionModalViewController 调用的 addEvent 函数,就像用户键入事件名称并发送 .save API 请求以将数据存储在数据库中一样。它工作正常,我的意思是成功添加数据后端并在集合视图列表中显示新事件。但是,问题是集合视图的 indexPath 没有更新。
例如,如果集合视图中已经有两个事件,则它们的indexPath 为[0,0] and [0,1]
。 (我在 print("here is the indexPath: \(indexPath)")
中将它们打印出来)
而我添加新事件后,collection view上有3个事件,是正确的,但是indexPath变成了[0,0],[0,0] and [0,1]
。所以我认为已经显示的事件的 indexPath 没有更新。应用快照不足以更新每个单元格的 indexPath 吗?我在想即使在应用快照之后,它仍然需要重新加载集合视图以将新的 indexPath 应用到单元格,或类似的东西。
有人遇到过同样的问题吗?如果是这样,您如何将新的 indexPath 应用于单元格? 我还有一个删除单元格的功能,但它也不会更新 indexPath。 顺便说一句,我正在开发 iOS14 的应用程序,所以不能将一个应用程序用于 iOS15...
private var eventDataSource = EventDataSource()
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView() // -> create collection view and set constraints
configureDataSource()
displayEvents()
}
func configureDataSource() {
let cellRegistration = UICollectionView.CellRegistration<ListCell, Event> { cell, indexPath, Event in
cell.Event = Event
let moreAction = UIAction(image: Images.setting) { _ in
let vc = EventActionModalViewController();
vc.modalPresentationStyle = .overCurrentContext
print("here is the indexPath: \(indexPath)")
vc.indexPath = indexPath
self.tabBarController?.present(vc, animated: false, completion: nil)
}
let moreActionButton = UIButton(primaryAction: moreAction)
moreActionButton.tintColor = UIColor.ouchienLightGray()
let moreActionAccessory = UICellAccessory.CustomViewConfiguration(
customView: moreActionButton,
placement: .trailing(displayed: .whenEditing, at: { _ in return 0 })
)
cell.accessories = [
.customView(configuration: moreActionAccessory),
.disclosureIndicator(displayed: .whenNotEditing, options: .init(tintColor: .systemGray))
]
}
dataSource = UICollectionViewDiffableDataSource<Section, Event>(collectionView: collectionView) {
(collectionView, indexPath, Event) -> UICollectionViewCell? in
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: Event)
return cell
}
}
func displayEvents() {
eventDataSource.fetchEvents { [weak self] in
self?.applySnapshot(animatingDifferences: true)
}
}
func addEvent(EventTitle: String) {
eventDataSource.save(eventTitle: EventTitle, completion: { [weak self] in
self?.applySnapshot(animatingDifferences: true)
})
}
func applySnapshot(animatingDifferences: Bool = true) {
snapshot = NSDiffableDataSourceSnapshot<Section, Event>()
snapshot.appendSections([.List])
snapshot.appendItems(eventDataSource.Events)
dataSource?.apply(snapshot, animatingDifferences: animatingDifferences)
}
您在 moreAction
中传递的索引路径是在单元格注册时捕获的索引路径,只有在创建单元格时才会发生这种情况,但不会回收。
您需要随时调用UICollectionView.indexPathForCell
获取正确的索引。