13

我正在查看 iOS13 中可用的 DiffableDataSource(或在此处向后移植:https ://github.com/ra1028/DiffableDataSources )并且无法弄清楚如何在您的集合或表格视图中支持多种单元格类型。

Apple 的示例代码1具有:

var dataSource: UICollectionViewDiffableDataSource<Section, OutlineItem>! = nil

这似乎迫使数据源成为单个单元格类型。如果我为另一种单元格类型创建一个单独的数据源——那么不能保证两个数据源没有同时apply调用它们——这会导致可怕NSInternalInconsistencyException——任何尝试动画的人都熟悉使用 . 手动插入/删除单元格performBatchUpdates

我错过了一些明显的东西吗?

4

2 回答 2

18

我将我的不同数据包装在一个enum带有关联值的文件中。就我而言,我的数据源是 type ,在UICollectionViewDiffableDataSource<Section, Item>哪里Item

enum Item: Hashable {
  case firstSection(DataModel1)
  case secondSection(DataModel2)
}

然后在传递给数据源初始化的闭包中,您会得到一个Item,并且您可以根据需要测试和解包数据。

(我要补充一点,您应该确保您的支持关联值是Hashable,否则您需要实现它。这就是 diff'ing 算法用来识别每个单元格并解决运动等问题)

于 2020-01-15T21:08:37.110 回答
9

您肯定需要有一个数据源。

关键是使用更通用的类型。斯威夫特AnyHashable在这里工作得很好。您只需要将实例AnyHashable转换为更具体的类。

lazy var dataSource = CollectionViewDiffableDataSource<Section, AnyHashable> (collectionView: collectionView) { collectionView, indexPath, item in

        if let article = item as? Article, let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Section.articles.cellIdentifier, for: indexPath) as? ArticleCell {
            cell.article = article
            return cell
        }

        if let image = item as? ArticleImage, let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Section.trends.cellIdentifier, for: indexPath) as? ImageCell {
            cell.image = image
            return cell
        }

        fatalError()
    }

Section 枚举如下所示:

    enum Section: Int, CaseIterable {
        case articles
        case articleImages

        var cellIdentifier: String {
            switch self {
            case .articles:
                return "articleCell"
            case .articleImages:
                return "imagesCell"
            }
        }
    }

于 2019-08-14T20:28:10.550 回答