【问题标题】:collection view list cell when the cell is added / deleted, how to update the indexPath of the cell?添加/删除单元格时的集合视图列表单元格,如何更新单元格的indexPath?
【发布时间】:2022-01-07 20:10:58
【问题描述】:

我正在处理集合视图列表单元格,我想知道当我在 iOS14 上使用 diffable 数据源和快照时如何更新 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)
}

【问题讨论】:

  • 在应用快照工作后添加 collectionView.reloadData() ......但这是我应该如何解决这个问题吗?我认为 diffabledata 源将处理所有应用的 cahges。

标签: ios swift uicollectionview indexpath diffabledatasource


【解决方案1】:

您在moreAction 中传递的索引路径是在单元注册时捕获的,只有在创建单元时才会发生这种情况,但不会被回收。

您需要随时致电UICollectionView.indexPathForCell 获取正确的索引。

【讨论】:

  • @Mosse 感谢您的评论。我不知道有 indexPathForCell。我现在就试试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多