16. 创建简单的列表布局
简单列表示例演示如何创建适应任何屏幕大小的基本列表布局。它使用系统定义的列表外观之一创建配置。然后,它通过将配置传递给list来创建列表布局list(using:)。这种方法生成一个组合布局,其中一个部分的样式为列表。
let config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
return UICollectionViewCompositionalLayout.list(using: config)

17. 选择列表外观
列表外观示例显示每个UICollectionLayoutListConfiguration.Appearance. 单击导航栏中的外观名称可将列表更改为另一个外观,显示每个列表样式。每个列表都使用.firstItemInSection头模式,这使得列表的每个部分都可以展开和折叠。
var config = UICollectionLayoutListConfiguration(appearance: self.appearance)
config.headerMode = .firstItemInSection
18. 自定义列表单元格
带有自定义单元格的列表示例演示如何配置自定义列表单元格子类。该示例重点介绍CustomListCell,这是UICollectionViewListCell的一个自定义子类,它将多种子视图组合到一个单元格中。它使用内容配置设置这些视图的外观和内容。
updateConfiguration(using:)方法设置单元格的初始外观和内容。每次单元的配置状态更改时,系统都会调用此方法,以更新该新状态下单元的外观。要配置列表内容视图,它将获取当前状态的默认列表内容配置。
var content = defaultListContentConfiguration().updated(for: state)
然后,它自定义配置的值并将该配置分配给listContentView的configuration属性。
对于图像视图和标签,updateConfiguration(using:) 方法获取当前状态的默认值单元格配置,并将其存储在valueConfiguration中。它将此配置中预先配置的默认样式和度量复制到自定义视图中,以确保与系统样式的一致性。
categoryIconView.tintColor = valueConfiguration.imageProperties.resolvedTintColor(for: tintColor)
categoryIconView.preferredSymbolConfiguration = .init(font: valueConfiguration.secondaryTextProperties.font, scale: .small)
为了在collection视图中注册自定义cell子类,本例使用cell注册。cell注册使用每个单元对应项的数据配置每个item。它还增加了一个暴露标志的cell附件的cell。
let cellRegistration = UICollectionView.CellRegistration<CustomListCell, Item> { (cell, indexPath, item) in
cell.updateWithItem(item)
cell.accessories = [.disclosureIndicator()]
}
diffable data source在将Cell展示时注册该Cell。
return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item)

19. 构建具有多个截面类型的布局
emoji示例演示了如何创建包含多种类型的sections的合成布局。该示例在一个合成布局中包含正交滚动部分、大纲部分和列表部分。createLayout()方法定义每个section。
对于顶部部分,它通过设置orthogonalScrollingBehavior属性来启用水平滚动。
section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary
outline部分使用UICollectionLayoutListConfiguration.Appearance.sidebar概述列表外观。它使用一个section快照来创建一个层次数据结构。
let rootItem = Item(title: String(describing: category), hasChildren: true)
outlineSnapshot.append([rootItem])
let outlineItems = category.emojis.map { Item(emoji: $0) }
outlineSnapshot.append(outlineItems, to: rootItem)
列表部分使用UICollectionLayoutListConfiguration.Appearance.insetGrouped文件列表外观。此部分的配置为每个单元格添加一个滑动操作,使该单元格可以标记为收藏夹。
configuration.leadingSwipeActionsConfigurationProvider = { [weak self] (indexPath) in
guard let self = self else { return nil }
guard let item = self.dataSource.itemIdentifier(for: indexPath) else { return nil }
return self.leadingSwipeActionConfigurationForListCellItem(item)
}
每个部分都有相应的单元注册,以配置自己的单元类型。collection视图使用这些注册将要在每个部分中显示的已配置单元格展示。
switch section {
case .recents:
return collectionView.dequeueConfiguredReusableCell(using: self.configuredGridCell(), for: indexPath, item: item.emoji)
case .list:
return collectionView.dequeueConfiguredReusableCell(using: self.configuredListCell(), for: indexPath, item: item)
case .outline:
if item.hasChildren {
return collectionView.dequeueConfiguredReusableCell(using: self.configuredOutlineHeaderCell(), for: indexPath, item: item.title!)
} else {
return collectionView.dequeueConfiguredReusableCell(using: self.configuredOutlineCell(), for: indexPath, item: item.emoji)
}
}

20. 创建值单元格列表
emojiexplorer-List示例演示如何使用值单元格样式创建包含单元格的列表。它将具有默认值单元格样式的内容配置应用于列表中的每个单元格。

网友评论