ASCollectionView
UICollectionView & UITableView 的 SwiftUI 实现。以下是一些它的有用特性
- 支持 预加载 和 onAppear/onDisappear。
- 支持 单元格选择,自动支持 SwiftUI 编辑模式。
- 支持单元格的 自适应大小。
- 支持新的 UICollectionViewCompositionalLayout 以及任何其他 UICollectionViewLayout。
- 支持为 ASTableView 移除分隔符。
- 支持直接使用 FetchedResults 作为数据源。
欢迎拉取请求和建议 :)。
目录
演示应用截图
入门指南
ASCollectionView 是一个 Swift Package。
- 可以使用 Xcode 的“File”菜单中的新 Swift Packages 选项将其导入到应用程序项目中。
- 当被问到时,请使用此存储库的 URL:https://github.com/apptekstudios/ASCollectionView
或者,如果由于某些原因无法使用 SPM,可以使用 Cocoapods 导入:pod 'ASCollectionView-SwiftUI', '~> 1.3'
使用方法
基本示例 - 单个部分
import ASCollectionView
import SwiftUI
struct SingleSectionExampleView: View
{
@State var dataExample = (0 ..< 30).map { $0 }
var body: some View
{
ASCollectionView(data: dataExample, dataID: \.self)
{ item, _ in
Color.blue
.overlay(Text("\(item)"))
}
.layout
{
.grid(
layoutMode: .adaptive(withMinItemSize: 100),
itemSpacing: 5,
lineSpacing: 5,
itemSize: .absolute(50))
}
}
}
带有唯一数据源的多部分
以下是如何包含包含两个部分(每个部分都有自己的数据源)的集合视图的示例。有关包含自定义组合布局的更详细示例,请参阅此处。或者,要获得更深入的解释,请下载此回购存储库中包含的示例项目。
import SwiftUI
import ASCollectionView
struct ExampleView: View
{
@State var dataExampleA = (0 ..< 21).map { $0 }
@State var dataExampleB = (0 ..< 15).map { "ITEM \($0)" }
var body: some View
{
ASCollectionView
{
ASCollectionViewSection(
id: 0,
data: dataExampleA,
dataID: \.self)
{ item, _ in
Color.blue
.overlay(
Text("\(item)")
)
}
ASCollectionViewSection(
id: 1,
data: dataExampleB,
dataID: \.self)
{ item, _ in
Color.green
.overlay(
Text("Complex layout - \(item)")
)
}
.sectionHeader
{
Text("Section header")
.padding()
.frame(maxWidth: .infinity, alignment: .leading) // Fill width and align text to the left
.background(Color.yellow)
}
.sectionFooter
{
Text("This is a section footer!")
.padding()
}
}
.layout
{ sectionID in
switch sectionID
{
case 0:
// Here we use one of the provided convenience layouts
return .grid(
layoutMode: .adaptive(withMinItemSize: 100),
itemSpacing: 5,
lineSpacing: 5,
itemSize: .absolute(50))
default:
return ASCollectionLayoutSection
{ environment in
// ...
// You could return any custom NSCollectionLayoutSection here. For an example see this file: /readmeAssets/SampleUsage.swift
// ...
}
}
}
}
}
辅助视图
ASCollectionView 支持辅助视图。要添加辅助视图,请使用 ASCollectionViewSection 的 sectionHeader
、sectionFooter
或 sectionSupplementary
修饰符。
sectionHeader
和sectionFooter
分别将辅助设置设置为UICollectionView.elementKindSectionHeader
和UICollectionView.elementKindSectionFooter
。sectionSupplementary
允许您指定任何辅助类型。
ASCollectionViewSection(...) { ... }
.sectionHeader
{
Text("Section header")
.background(Color.yellow)
}
.sectionFooter
{
Text("Section footer")
.background(Color.blue)
}
.sectionSupplementary(ofKind: "someOtherSupplementaryKindRequestedByYourLayout")
{
Text("Section supplementary")
.background(Color.green)
}
装饰视图
UICollectionViewLayout可以布局与数据无关的装饰视图(例如,部分背景)。这些不能被配置,因此您必须提供一个可以使用.init()初始化的View结构体。
- 为了强制执行这一要求,您的视图必须符合
Decoration
协议。这个协议唯一的要求是一个无参数的初始化器。 - 您必须将视图类型注册到布局中。
- 请参阅演示应用的提醒界面以获取一个工作示例。
声明符合Decoration
的Swift视图
struct GroupBackground: View, Decoration
{
let cornerRadius: CGFloat = 12
var body: some View
{
RoundedRectangle(cornerRadius: cornerRadius)
.fill(Color(.secondarySystemGroupedBackground))
}
}
将装饰类型与布局注册(ASCollectionLayout)
var layout: ASCollectionLayout<Section>
{
ASCollectionLayout<Section>
{
// ... Here is an example of including a decoration in a compositional layout.
let sectionBackgroundDecoration = NSCollectionLayoutDecorationItem.background(elementKind: "groupBackground")
sectionBackgroundDecoration.contentInsets = section.contentInsets
section.decorationItems = [sectionBackgroundDecoration]
// ...
}
.decorationView(GroupBackground.self, forDecorationViewOfKind: "groupBackground") // REGISTER the decoration view type
}
布局
- 内置了对新的UICollectionViewCompositionalLayout的支持。
- 您可以在每个部分的基础上定义布局,包括使用switch语句(如果需要)。
- 工作正在进行中:有一些有用的方法可以轻松定义基于列表和网格的布局(包括正交网格)。
定义所有部分的布局
ASCollectionView(...) { ... }
.layout
{
ASCollectionLayoutSection
{ layoutEnvironment in
// Construct and return a NSCollectionLayoutSection here
}
}
按部分定义布局
ASCollectionView(...) { ... }
.layout
{ sectionID in
switch sectionID
{
case .userSection:
return ASCollectionLayoutSection
{ layoutEnvironment in
// Construct and return a NSCollectionLayoutSection here
}
}
case .postSection:
return ASCollectionLayoutSection
{ layoutEnvironment in
// Construct and return a NSCollectionLayoutSection here
}
}
使用自定义UICollectionViewLayout
ASCollectionView(...) { ... }
.layout
{
let someCustomLayout = CustomUICollectionViewLayout()
someCustomLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
return someCustomLayout
}
其他技巧
- 您可以使用枚举作为您的SectionID(而不是仅使用Int),这使您能够轻松确定每个部分的布局。
- 有关更深入的用法示例,请参阅演示项目。
- 请注意,您应仅使用@State在集合视图单元格中设置短暂可见状态。任何您希望持久存储的内容应存储在您的模型中。
待办事项
请参阅公开问题以获取要提出的功能(以及已知的问题)列表。
许可证
在MIT许可证下分发。有关更多信息,请参阅LICENSE
。