考虑一个UICollectionView
带有流式布局和水平方向的布局。默认情况下,单元格按从上到下、从左到右的顺序排列。像这样:
1 4 7 10 13 16
2 5 8 11 14 17
3 6 9 12 15 18
在我的例子中,collection view 是分页的,并且它的设计使得特定数量的单元格适合每个页面。因此,更自然的排序将是:
1 2 3 10 11 12
4 5 6 - 13 14 15
7 8 9 16 17 18
除了实现我自己的自定义布局之外,最简单的实现方式是什么?特别是,我不想放弃任何免费提供的功能UICollectionViewFlowLayout
(例如插入/删除动画)。
或者一般来说,您如何f(n)
在流布局上实现重新排序功能?例如,这同样适用于从右到左的排序。
到目前为止我的方法
我的第一种方法是子类化UICollectionViewFlowLayout
和覆盖layoutAttributesForItemAtIndexPath:
:
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *reorderedIndexPath = [self reorderedIndexPathOfIndexPath:indexPath];
UICollectionViewLayoutAttributes *layout = [super layoutAttributesForItemAtIndexPath:reorderedIndexPath];
layout.indexPath = indexPath;
return layout;
}
reorderedIndexPathOfIndexPath:
在哪里f(n)
。通过调用super
,我不必手动计算每个元素的布局。
此外,我必须覆盖layoutAttributesForElementsInRect:
,这是布局用来选择要显示哪些元素的方法。
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *result = [NSMutableArray array];
NSInteger sectionCount = 1;
if ([self.collectionView.dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)])
{
sectionCount = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView];
}
for (int s = 0; s < sectionCount; s++)
{
NSInteger itemCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:s];
for (int i = 0; i < itemCount; i++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:s];
UICollectionViewLayoutAttributes *layout = [self layoutAttributesForItemAtIndexPath:indexPath];
if (CGRectIntersectsRect(rect, layout.frame))
{
[result addObject:layout];
}
}
}
return result;
}
在这里,我只是尝试每个元素,如果它在给定的范围内rect
,我将其返回。
如果这种方法是要走的路,我有以下更具体的问题:
- 有什么办法可以简化
layoutAttributesForElementsInRect:
覆盖,或者提高效率? - 我错过了什么吗?至少交换不同页面的单元格会产生奇怪的结果。我怀疑它与
initialLayoutAttributesForAppearingItemAtIndexPath:
and相关finalLayoutAttributesForDisappearingItemAtIndexPath:
,但我无法准确指出问题所在。 - 就我而言,
f(n)
取决于每页的列数和行数。除了自己硬编码之外,有没有什么方法可以从中提取这些信息UICollectionViewFlowLayout
?我想过用集合视图的边界进行查询layoutAttributesForElementsInRect:
,并从那里推导出行和列,但这也感觉效率低下。