将UICollectionViewFlowLayout配置为从下到上布局行

时间:2014-05-17 20:01:05

标签: ios uicollectionview

默认情况下(即,使用垂直滚动方向),UICollectionViewFlowLayout通过从左上角开始,从左到右,直到行被填充,然后继续,布局单元格到下一行 down 。相反,我希望它从左下角开始,从左到右,直到行被填充,然后继续到下一行向上。 / p>

通过继承UIScrollViewFlowLayout是否有直接的方法来实现这一点,或者我是否基本上需要从头开始重新实现该类?

Apple关于子流程布局的documentation建议我只需要覆盖并重新实现我自己的layoutAttributesForElementsInRect:layoutAttributesForItemAtIndexPath:collectionViewContentSize版本。但这似乎并不简单。由于UICollectionViewFlowLayout没有公开它在prepareLayout内部进行的任何网格布局计算,因此我需要从顶部到底部生成的值中推导出从底部到顶部布局所需的所有布局值。布局。

我不确定这是可能的。虽然我可以重新使用其关于哪些项目组放在同一行上的计算,但我需要计算新的y偏移量。为了进行计算,我需要有关所有项目的信息,但这些超类方法不会报告。

3 个答案:

答案 0 :(得分:4)

@ insane-36的非常有用的答案显示了collectionView.bounds == collectionView.collectionViewContentSize时的方法。

但如果您希望支持collectionView.bounds < collectionViewcontentSize的情况,那么我认为您需要重新映射这些rect以正确支持滚动。如果您希望支持collectionView.bounds > collectionViewContentSize的情况,那么您需要覆盖collectionViewContentSize以确保内容rect位于collectionView的底部(否则它将位于顶部,由于UIScrollView)的从上到下的默认行为。

所以完整的解决方案涉及更多,我最终在这里开发了它:https://github.com/algal/ALGReversedFlowLayout

答案 1 :(得分:3)

你基本上可以用一个简单的逻辑来实现它,但这似乎有些奇怪。如果集合视图内容大小与集合视图边界相同,或者如果所有单元格都可见,那么您可以使用简单的flowLayout实现此目的,

@implementation SimpleFlowLayout


- (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
  UICollectionViewLayoutAttributes *attribute = [super layoutAttributesForItemAtIndexPath:indexPath];
  [self modifyLayoutAttribute:attribute];
  return attribute;
}

- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{
  NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
  for(UICollectionViewLayoutAttributes *attribute in attributes){
    [self modifyLayoutAttribute:attribute];
  }
  return attributes;
}


- (void)modifyLayoutAttribute:(UICollectionViewLayoutAttributes*)attribute{
  CGSize contentSize = self.collectionViewContentSize;
  CGRect frame = attribute.frame;
  frame.origin.x = contentSize.width - attribute.frame.origin.x - attribute.frame.size.width;
  frame.origin.y = contentSize.height - attribute.frame.origin.y - attribute.frame.size.height;
  attribute.frame = frame;

}

@end

所以这个数字看起来像这样,

enter image description here

但是,如果您使用更多行,同时可以在屏幕上看到更多行,那么重用似乎存在一些问题。由于UICollectionView数据源方法,collectionView:cellForItemAtIndexPath:线性工作并在用户滚动时请求indexPath,因此按照通常增加的indexPath模式(例如1 --- 100)询问单元格,尽管我们希望它反转此模式。滚动时我们需要collectionView按递减顺序询问我们的项目,因为我们的100项目位于顶部,1项位于底部。所以,我对如何实现这一点没有任何特别的想法。

答案 2 :(得分:0)

UICollectionView具有反向的流布局。

["h","e","l","l","o"]