UICollectionViewFlowLayout - 为某些项目强制换行
UICollectionViewFlowLayout - Force new line for some items
我有一个带有流布局的垂直滚动 collection 视图。我已经对布局 object 进行了子类化,以便将元素对齐到每一行的左侧(从这里和那里借来的代码),并将 headers 部分放在每行的左边距(插图)上部分(而不是上面),但除此之外它只是一个流布局。
我想强制 一些 项目(不是全部)的单元格放置 "on the next line",即使有足够的空间将它们放在右侧先前放置的单元格。
我唯一可以看到自己这样做的地方是重写 UICollectionViewFlowLayout
方法时 layoutAttributesForItemAtIndexPath(_:)
。
但是,只有 delegate/data 来源知道 哪些 项需要换行,none UICollectionViewDelegate
中的方法,UICollectionViewDataSource
或 UICollectionViewDelegateFlowLayout
似乎给了我一个具体说明的机会。
实现此目标的优雅方式是什么?
你说得对,UICollectionViewFlowLayout
是为在你的 collectionView 中定位项目而设计的。
您可以结合使用 layoutAttributesForItemAtIndexPath
和 layoutAttributesForElementsInRect
来设置项目位置,如下所述:
对于您的情况,您有多种解决方案来确定每个项目在 collectionView 中的位置:
- 在你的子类
UICollectionViewFlowLayout
的collectionView中定义每个item和supplementary view的绝对位置
- 让
UICollectionViewFlowLayout
的子类决定某个项目是否需要换行并更改其 UICollectionViewLayoutAttributes
创建一个新的协议子类 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 外观,您仍然可以从一种自定义布局切换到另一种自定义布局。
我有一个带有流布局的垂直滚动 collection 视图。我已经对布局 object 进行了子类化,以便将元素对齐到每一行的左侧(从这里和那里借来的代码),并将 headers 部分放在每行的左边距(插图)上部分(而不是上面),但除此之外它只是一个流布局。
我想强制 一些 项目(不是全部)的单元格放置 "on the next line",即使有足够的空间将它们放在右侧先前放置的单元格。
我唯一可以看到自己这样做的地方是重写 UICollectionViewFlowLayout
方法时 layoutAttributesForItemAtIndexPath(_:)
。
但是,只有 delegate/data 来源知道 哪些 项需要换行,none UICollectionViewDelegate
中的方法,UICollectionViewDataSource
或 UICollectionViewDelegateFlowLayout
似乎给了我一个具体说明的机会。
实现此目标的优雅方式是什么?
你说得对,UICollectionViewFlowLayout
是为在你的 collectionView 中定位项目而设计的。
您可以结合使用 layoutAttributesForItemAtIndexPath
和 layoutAttributesForElementsInRect
来设置项目位置,如下所述:
对于您的情况,您有多种解决方案来确定每个项目在 collectionView 中的位置:
- 在你的子类
UICollectionViewFlowLayout
的collectionView中定义每个item和supplementary view的绝对位置
- 让
UICollectionViewFlowLayout
的子类决定某个项目是否需要换行并更改其UICollectionViewLayoutAttributes
创建一个新的协议子类
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 外观,您仍然可以从一种自定义布局切换到另一种自定义布局。