简体   繁体   English

添加/删除单元格时的集合视图列表单元格,如何更新单元格的indexPath?

[英]collection view list cell when the cell is added / deleted, how to update the indexPath of the cell?

I'm working on the collection view list cell and I was wondering how to update the indexPath when I use the diffable data source and snapshot on iOS14.我正在处理集合视图列表单元格,我想知道当我在 iOS14 上使用 diffable 数据源和快照时如何更新 indexPath。

In my ViewController's viewdidload, I called configureDataSource method which registers cell information.在我的 ViewController 的 viewdidload 中,我调用了注册单元信息的 configureDataSource 方法。 Also, I have a displayEvents method that fetches Events data from the backend and displays them on the collection view cell.另外,我有一个 displayEvents 方法,它从后端获取事件数据并将它们显示在集合视图单元格上。 The eventDataSource holds an array of Events, so when the Event data are fetched, it updates the array so the ViewController can display data. eventDataSource 包含一个事件数组,因此当获取事件数据时,它会更新数组,以便 ViewController 可以显示数据。

I also have an addEvent function which is called from EventActionModalViewController, like a user types the event name and sends.save API request to store the data in the database.我还有一个 addEvent function,它是从 EventActionModalViewController 调用的,就像用户键入事件名称并发送.save API 请求以将数据存储在数据库中一样。 It works fine, I mean successfully add data backend and display the new event on the collection view list.它工作正常,我的意思是成功添加数据后端并在集合视图列表上显示新事件。 However, the problem is the collection view's indexPath is not updated.但是,问题是集合视图的 indexPath 没有更新。

For instance, if there are already two events in the collection view, their indexPath are [0,0] and [0,1] .例如,如果集合视图中已经有两个事件,它们的 indexPath 是[0,0] and [0,1] (I printed them out in print("here is the indexPath: \(indexPath)") ) And after I add the new event, there are three events on the collection view, which is correct, but the indexPath becomes [0,0],[0,0] and [0,1] . (我在print("here is the indexPath: \(indexPath)")它们打印出来)并且添加新事件后,集合视图上有三个事件,这是正确的,但是 indexPath 变为[0,0],[0,0] and [0,1] So I think the indexPath of already displayed events are not updated.所以我认为已经显示事件的 indexPath 没有更新。 Is applying a snapshot not enough to update the indexPath of each cell?应用快照不足以更新每个单元格的 indexPath 吗? I was thinking even after applying snapshot, it still needs to reload the collection view to apply a new indexPath to the cell, or something similar.我在想即使在应用快照之后,它仍然需要重新加载集合视图以将新的 indexPath 应用到单元格,或者类似的东西。

Has anyone faced the same issue?有没有人遇到过同样的问题? If so, how did you apply the new indexPath to the cell?如果是这样,您是如何将新的 indexPath 应用到单元格的? I also have a function to delete the cell, but it doesn't update the indexPath as well.我还有一个 function 来删除单元格,但它也不会更新 indexPath。 Btw, I'm working on the app for iOS14, so cannot use one for iOS15...顺便说一句,我正在开发适用于 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)
}

The index path you pass in moreAction is the one captured at cell registration, which happens only if cell is created, but not recycled.您在moreAction中传递的索引路径是在单元格注册时捕获的路径,只有在创建单元格时才会发生这种情况,但不会被回收。

You need to call UICollectionView.indexPathForCell to get the right index at any time.您需要随时调用UICollectionView.indexPathForCell来获取正确的索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM