我正在开发我已经在 Android 上开发的应用的 iOS 版本。此应用程序具有以下 2 列自调整大小(固定宽度但可变高度)单元格的网格:
在 Android 版本中实现这一点很容易,因为 Google 为其 RecyclerView
提供了一个 StaggeredGridLayoutManager
。您指定列数和滚动方向即可。
默认的 UICollectionView
布局 UICollectionViewFlowLayout
不允许我正在寻找的交错布局,因此我必须实现自定义布局。我看过 2 个讨论这个主题的 WWDC 视频(What's New in Table and Collection Views 和 Advanced User Interfaces with Collection Views),我或多或少知道应该如何实现。
第 1 步。首先计算布局的近似值。
第 2 步。然后创建单元格并使用自动布局调整大小。
第 3 步。然后 Controller 通知单元格大小,以便更新布局。
在尝试对这些步骤进行编码时,我产生了疑虑。我找到了一个 tutorial这解释了创建具有交错列的自定义布局,但它不使用自动布局来获取单元格的大小。这给我留下了以下问题:
在第2步中,如何以及何时可以获取单元格大小?
在第3步中,如何以及何时通知布局更改?
最佳答案
我想指出,正如您所提到的,RayWenderlich PinInterest Layout正是帮助您实现此布局的教程。
回答您的问题 - 关于教程:
在第2步中,如何以及何时可以获取单元格大小?
为了获取单元格高度,在自定义 UICollectionViewLayout
的 prepareLayout
方法中调用了一个委托(delegate)方法。此方法被调用一次(或两次,我只是尝试使用print
语句运行它,我得到了两次调用)。 prepareLayout
的要点是初始化单元格的 frame
属性,换句话说,提供每个单元格的确切大小。我们知道宽度是不变的,只有height
是变化的,所以在prepareLayout
的这一行中:
let cellHeight = delegate.collectionView(collectionView!,
heightForItemAtIndexPath: indexPath, withWidth: width)
我们从 UICollectionViewController
中实现的委托(delegate)方法获取单元格的高度。对于我们要在 collectionView
中显示的所有单元格,都会发生这种情况。在获取并修改每个单元格的高度后,我们缓存结果以便稍后检查。
之后,collectionView
要获取屏幕上每个单元格的大小,它需要做的就是查询缓存中的信息。这是在自定义 UICollectionViewLayout
类的 layoutAttributesForElementsInRect
方法中完成的。
此方法由 UICollectionViewController
自动调用。当 UICollectionViewController
需要出现在屏幕上的单元格的布局信息时(例如,由于滚动或首次加载),您从填充的缓存中返回属性准备布局
。
关于您的问题的结论:在第 2 步中,我如何以及何时可以获得像元大小?
回答:每个单元格大小都是在您的自定义 UICollectionViewFlowLayout
的 prepareLayout
方法中获得的,并且在您的单元格生命周期的早期计算UICollectionView
。
在第3步中,如何以及何时通知布局更改?
请注意,本教程不考虑在运行时添加的新单元格:
Note: As prepareLayout() is called whenever the collection view’s layout is invalidated, there are many situations in a typical implementation where you might need to recalculate attributes here. For example, the bounds of the UICollectionView might change – such as when the orientation changes – or items may be added or removed from the collection. These cases are out of scope for this tutorial, but it’s important to be aware of them in a non-trivial implementation.
正如他所写,这是一个您可能需要的重要实现。但是,如果您的数据集很小(或出于测试目的),您可能会采用一个简单(非常低效)的实现。当由于屏幕旋转或添加/删除单元格而需要使布局无效时,您可以清除自定义 UICollectionViewFlowLayout
中的缓存以强制 prepareLayout
重新初始化布局属性。
例如,当您必须在 collectionView 上调用 reloadData
时,还要调用您的自定义布局类,以删除缓存:
cache.removeAll()
关于ios - 如何开发一个自定义的 UICollectionViewLayout,它具有带有自动调整单元格的交错列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32398232/