UICollectionViewFlowLayout - 为某些项目强制换行

UICollectionViewFlowLayout - Force new line for some items

我有一个带有流布局的垂直滚动 collection 视图。我已经对布局 object 进行了子类化,以便将元素对齐到每一行的左侧(从这里和那里借来的代码),并将 headers 部分放在每行的左边距(插图)上部分(而不是上面),但除此之外它只是一个流布局。

我想强制 一些 项目(不是全部)的单元格放置 "on the next line",即使有足够的空间将它们放在右侧先前放置的单元格。

我唯一可以看到自己这样做的地方是重写 UICollectionViewFlowLayout 方法时 layoutAttributesForItemAtIndexPath(_:)

但是,只有 delegate/data 来源知道 哪些 项需要换行,none UICollectionViewDelegate 中的方法,UICollectionViewDataSourceUICollectionViewDelegateFlowLayout 似乎给了我一个具体说明的机会。

实现此目标的优雅方式是什么?

你说得对,UICollectionViewFlowLayout 是为在你的 collectionView 中定位项目而设计的。

您可以结合使用 layoutAttributesForItemAtIndexPathlayoutAttributesForElementsInRect 来设置项目位置,如下所述:

对于您的情况,您有多种解决方案来确定每个项目在 collectionView 中的位置:

  1. 在你的子类UICollectionViewFlowLayout
  2. 的collectionView中定义每个item和supplementary view的绝对位置
  3. UICollectionViewFlowLayout 的子类决定某个项目是否需要换行并更改其 UICollectionViewLayoutAttributes
  4. 创建一个新的协议子类 UICollectionViewDelegateFlowLayout 并添加一个类似 - (BOOL)shouldItemBePlacedOnTheNextLineAtIndexPath: 的方法,然后在 UICollectionViewFlowLayout 的子类中调用此方法,如下所示:

    BOOL shouldPlaceOnNextLine = NO;

    id < MySubProtocolOfUICollectionViewDelegate > flowLayoutDelegate = (id < MySubProtocolOfUICollectionViewDelegate >)self.collectionView.delegate;
    if ([flowLayoutDelegate respondsToSelector:@selector(shouldItemBePlacedOnTheNextLineAtIndexPath:)]) {
        shouldPlaceOnNextLine = [flowLayoutDelegate shouldItemBePlacedOnTheNextLineAtIndexPath:indexPath]
    }
    

但是,我建议您采用第一种解决方案:让 UICollectionViewFlowLayout 的子类确定项目和补充视图的位置,如果您在 dataSource/delegate 中调用 [(MyCustomFlowLayout *)self.collectionView.collectionViewLayout isItemForceOnNewLine]需要它。

在我看来,这是最优雅的解决方案,因为如果您想动态更改 collectionView 外观,您仍然可以从一种自定义布局切换到另一种自定义布局。