【发布时间】:2013-03-30 13:43:09
【问题描述】:
考虑一个具有流式布局和水平方向的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:和finalLayoutAttributesForDisappearingItemAtIndexPath:有关,但我无法确定到底是什么问题。 - 就我而言,
f(n)取决于每页的列数和行数。有没有办法从UICollectionViewFlowLayout中提取这些信息,而不是自己硬编码?我想到了 queryinglayoutAttributesForElementsInRect:与集合视图的边界,并从那里推导出行和列,但这也感觉效率低下。
【问题讨论】:
-
我想知道在分页滚动视图中拥有多个集合视图是否更容易,这样第一个集合视图将包含水平布局的项目 1 到 9,第二个集合视图包含项目 10 -18 等
-
@rdelmar 感觉就像重新实现了很多我通过
UICollectionView免费获得的东西。不过,没有尝试将集合分成几部分。 -
不幸的是,您似乎必须重新实现很多...请参阅我的回答。但至少它会非常可重用。 :)
标签: ios ios6 uicollectionview uicollectionviewlayout