在 UICollectionView 中将两个部分并排放置
Placing two sections next to each other in a UICollectionView
我有一个包含 6 个部分的 CollectionView。
第一部分组织为行。第 2 和第 3 节是事情变得困难的地方。 我需要将两个部分并排放置。
[................第 1 部分................] // 一个部分有几行
[...第 2 节...][...第 3 节...] // 第一个
下面的两个部分
我无法将第二部分分成两列,因为它们填充了不同的单元格。
知道流布局总是从一个边界到另一个边界填满一个部分,我只能通过将两个单元格彼此相邻来伪造这种效果,这很好,但我添加单元格并且我只能将一个放在另一个下面用一个整数每次我在 cellForItemAtIndexPath: 中创建一个新单元格并使用它乘以单元格的高度时它都会增加。
我当时面临的唯一问题是,当我重复使用某些单元格时,整数变量 hack 不再起作用。
除了自定义布局之外,还有没有更好的方法将两个部分并排放置?
提前致谢
您不一定要编写自定义布局,实际上您可以继承 UICollectionViewFlowLayout
并覆盖一些确定框架定位的关键方法,即 layoutAttributesForElementsInRect:
/ layoutAttributesForItemAtIndexPath:
您可以在其中查看该部分并确定位置。
代码本身可能相对简单,大致如下:
if indexPath.section == 0 {
attributes.frame = CGRect(x: 0, y: 0, width: fullWidth, height: someHeight)
} else {
// Section 2 which is indexed at 1, set the frame
// to half the width and x to 0
if indexPath.section %2 != 0 {
attributes.frame = CGRect(x: 0, y: someYCounter, width: halfWidth, height, someHeight)
} else {
attributes.frame = CGRect(x: halfWidth, y: someYCounter, width: halfWidth, height, someHeight)
}
}
显然这是伪代码,我还没有通过编译器 运行,但基本步骤是:
- 有一个保证collection view存在的guard语句,所以可以定义如下变量:
halfWidth
和fullWidth
(后面布局时用到)
- 保持你的
y
位置的 运行ning 计数器
- 适当检查章节索引和位置
解决此问题的最佳方法是覆盖 prepare 并计算布局属性数组(并将其存储为实例变量)。然后在 layoutAttributesForItemAtIndexPath:
等中,只是 return 该数组中索引处的对象(或者如果索引由于某种原因超出范围,return super.layoutAttributesForItem(at: indexPath)
.
这就是 UICollectionViewFlowLayout
的美妙之处,大部分繁重的工作都为您完成,您可以子类化一些简单的方法以获得所需的行为。替代方案是完全成熟的自定义布局,在我看来,除非您有一些疯狂的行为,否则很少有理由这样做,在这种情况下,您应该与您的设计师讨论他们制作的东西的复杂性。
我有一个包含 6 个部分的 CollectionView。
第一部分组织为行。第 2 和第 3 节是事情变得困难的地方。 我需要将两个部分并排放置。
[................第 1 部分................] // 一个部分有几行
[...第 2 节...][...第 3 节...] // 第一个
我无法将第二部分分成两列,因为它们填充了不同的单元格。
知道流布局总是从一个边界到另一个边界填满一个部分,我只能通过将两个单元格彼此相邻来伪造这种效果,这很好,但我添加单元格并且我只能将一个放在另一个下面用一个整数每次我在 cellForItemAtIndexPath: 中创建一个新单元格并使用它乘以单元格的高度时它都会增加。
我当时面临的唯一问题是,当我重复使用某些单元格时,整数变量 hack 不再起作用。
除了自定义布局之外,还有没有更好的方法将两个部分并排放置?
提前致谢
您不一定要编写自定义布局,实际上您可以继承 UICollectionViewFlowLayout
并覆盖一些确定框架定位的关键方法,即 layoutAttributesForElementsInRect:
/ layoutAttributesForItemAtIndexPath:
您可以在其中查看该部分并确定位置。
代码本身可能相对简单,大致如下:
if indexPath.section == 0 {
attributes.frame = CGRect(x: 0, y: 0, width: fullWidth, height: someHeight)
} else {
// Section 2 which is indexed at 1, set the frame
// to half the width and x to 0
if indexPath.section %2 != 0 {
attributes.frame = CGRect(x: 0, y: someYCounter, width: halfWidth, height, someHeight)
} else {
attributes.frame = CGRect(x: halfWidth, y: someYCounter, width: halfWidth, height, someHeight)
}
}
显然这是伪代码,我还没有通过编译器 运行,但基本步骤是:
- 有一个保证collection view存在的guard语句,所以可以定义如下变量:
halfWidth
和fullWidth
(后面布局时用到) - 保持你的
y
位置的 运行ning 计数器 - 适当检查章节索引和位置
解决此问题的最佳方法是覆盖 prepare 并计算布局属性数组(并将其存储为实例变量)。然后在 layoutAttributesForItemAtIndexPath:
等中,只是 return 该数组中索引处的对象(或者如果索引由于某种原因超出范围,return super.layoutAttributesForItem(at: indexPath)
.
这就是 UICollectionViewFlowLayout
的美妙之处,大部分繁重的工作都为您完成,您可以子类化一些简单的方法以获得所需的行为。替代方案是完全成熟的自定义布局,在我看来,除非您有一些疯狂的行为,否则很少有理由这样做,在这种情况下,您应该与您的设计师讨论他们制作的东西的复杂性。