The main problem that I am facing is that I need information from a basic data source to configure the attributes of visible and invisible cells, as well as additional representations. The UICollectionViewDelegate protocol requires cells to be deleted after the layout attributes are already set, although the implementation class (usually the UICollectionViewController has access to the data source).
collection programming hints> so that the delegate object can be extended to provide additional information. Using UICollectionViewDelegateFlowLayout as a reference , I created a new protocol that declares methods for the data I need. My subclass of UICollectionViewController then complied with this protocol, implementing these methods without any layout operations (for example, to delete view objects).
My protocol looks something like this:
@protocol MyCollectionViewDelegateLayout <UICollectionViewDelegate> - (CGSize)sizeForCellAtIndexPath:(NSIndexPath *)indexPath; - (CGSize)sizeForHeaderAtIndexPath:(NSIndexPath *)indexPath; @end
My collection view controller has the following structure:
@interface MyCollectionViewController : UICollectionViewController <MyCollectionViewDelegateLayout> ... @end @implementation MyCollectionViewController ... - (CGSize)sizeForCellAtIndexPath:(NSIndexPath *)indexPath { // Make calculations based on data at index path. return CGSizeMake(width, height); } - (CGSize)sizeForHeaderAtIndexPath:(NSIndexPath *)indexPath; { // Make calculations based on data at index path. return CGSizeMake(width, height); }
Inside the prepareLayout method in my subclass of UICollectionViewLayout I call these methods to pre-compute the required attributes:
@implementation MyCollectionViewLayout ... - (void)prepareLayout { ... // Iterate over sections and rows... id dataSource = self.collectionView.dataSource; if ([dataSource respondsToSelector:@selector(sizeForCellAtIndexPath:)]) { CGSize size = [dataSource sizeForCellAtIndexPath:indexPath]; } else { // Use default values or calculate size another way } ... } ...
Using an extended data source protocol allows the code to support separation of concerns between MVCs. Here, the layout class still doesn't know anything about the underlying data, but can use it to define attributes. In contrast, the controller class does not post anything; instead, it provides only size hints based on the underlying data.
source share