ios - UICollectionView 使用 UICollectionViewFlowLayout 删除分节符

标签 ios objective-c swift uikit uicollectionviewlayout

我有一个分为多个部分的数据集,但是,我想在一个 collectionView 中显示它,而不在部分之间打断。这是我想要实现的目标的示例:

Instead of:
0-0 0-1 0-2
0-3
1-0 1-1
2-0
3-0

I want:
0-0 0-1 0-2
0-3 1-0 1-1
2-0 3-0

我意识到解决方案可能在于自定义 UICollectionViewLayout 子类,但我不确定如何实现这样的目标。

谢谢

最佳答案

您是正确的,您需要子类化 UICollectionViewLayout。 在开始之前要了解的本质是您需要至少计算 Collection View 中每个单元格的位置和大小。 UICollectionViewLayout 只是一种提供该信息的结构化方式。您获得了结构,但您必须自己提供其他所有内容。

您需要覆盖 4 个方法:

  • 准备
  • 无效布局
  • layoutAttributesForItemAtIndexPath
  • layoutAttributesForElementsInRect

一个技巧是将布局属性缓存在查找表(字典)中:

var cachedItemAttributes = [IndexPath: UICollectionViewLayoutAttributes]()

准备中,您计算​​ collectionView 中每个 indexPath 的布局属性:

override func prepare() {
    super.prepare()
    calculateAttributes()
}

invalidateLayout 中,您重置缓存的布局属性并重新计算它们:

override func invalidateLayout() {
    super.invalidateLayout()
    cachedItemAttributes = [:]
    calculateAttributes()
} 

layoutAttributesForItemAtIndexPath 中,您使用查找表返回正确的布局属性:

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    return cachedItemAttributes[indexPath]
}

layoutAttributesForElementsInRect 中,您可以针对指定矩形内的元素过滤查找表:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    return cachedItemAttributes.filter { rect.intersects($0.value.frame) }.map { $0.value }
}

拼图的最后一 block 是布局属性的实际计算。这里我只提供伪代码:

func calculateAttributes() {
    // For each indexpath (you can get this from the collectionView property using numberOfSections and numberOfItems:inSection )
    // calculate the frame, i.e the origin point and size of each cell in your collectionView and set it with UICollectionViewLayoutAttributes.frame
    // There are many other properties on UICollectionViewLayoutAttributes that you can tweak for your layout, but frame is a good starting point from which you can start experimenting.
    // Add the layout attributes to the lookup table
    // end loop
}

为了回答您的问题,这里是计算每个单元格位置的伪代码:

// If width of cell + current width of row + spacing, insets and margins exceeds the available width
// move to next row.
// else
// cell origin.x = current width of row + interitem spacing
// cell origin.y = number of rows * (row height + spacing)
// endif

如果您需要自定义布局是可配置的,那么在可用签名足够的情况下使用 UICollectionViewDelegateFlowLayout,或者定义您自己的继承自 UICollectionViewDelegateFlowLayout 或 UICollectionViewDelegate 的布局。因为您的协议(protocol)继承自 UICollectionViewDelegateFlowLayout,而 UICollectionViewDelegateFlowLayout 本身继承自 UICollectionViewDelegate,因此您可以直接将其设置为 View Controller 中的 collectionView 委托(delegate)。在您的自定义 Collection View 布局中,您只需将委托(delegate)从 UICollectionViewDelegate 转换为您的自定义协议(protocol)即可使用它。请记住处理转换失败或委托(delegate)未实现协议(protocol)方法的情况。

关于ios - UICollectionView 使用 UICollectionViewFlowLayout 删除分节符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36879230/

相关文章:

ios - EXC_CRASH (SIGABRT) 崩溃报告

ios - NSInvalidArgumentException',原因 : '-[UITableView setSeparatorInset:]: unrecognized selector sent to instance

iphone - 如何在 tmx map 中提取折线点?

iphone - ScrollView 仅在 View 出现第二次时才开始滚动

iphone - 检查是否在UIPinchGestureRecognizer中释放了捏

swift - 如何在不触发 "Instance will be immediately deallocated because property ' 的情况下实例化弱委托(delegate) tableViewDelegate' is 'weak' "

ios - 滚动表格 View 并单击搜索器崩溃应用程序

ios - navigationController 在执行 segue 时为零?

ios - AFNetworking - 可以让文件排队等待上传的异步上传任务(有进度)

swift - `UIImagePickerControllerOriginalImage ` 、 `UIImagePickerControllerCropRect ` 和 `UIImagePickerControllerEditedImage` 有什么关系?