`UICollectionViewLayout`如何访问不可见单元格的数据?

时间:2014-04-25 17:12:37

标签: ios uicollectionview uicollectionviewlayout

我想从数据源中获取所有数据 - 包括可见不可见单元格 - 以便计算可见单元格的属性。 collectionView:cellForItemAtIndexPath:无法正常工作,因为它会为不可见的单元格返回nil。如UICollectionView API中所述:

  

返回值

     

相应索引路径的单元格对象,如果单元格不可见或 indexPath 超出范围,则为nil

关于如何在不破坏MVC约束的情况下获取底层数据的任何想法(例如,在布局中存储对数据的引用)?

1 个答案:

答案 0 :(得分:3)

我面临的主要问题是我需要来自底层数据源的信息来设置可见和不可见单元格的属性,以及补充视图。 UICollectionViewDelegate协议要求在已经设置了布局属性之后将单元格出列,即使实现类(通常UICollectionViewController可以访问数据源)。 / p>

委托对象可以扩展的Collection View Programming Guide hints以提供其他信息。使用UICollectionViewDelegateFlowLayout作为reference,我创建了一个新协议,声明了我需要的数据的方法。然后我的UICollectionViewController子类通过实现这些方法符合该协议,没有任何布局操作(如出列视图单元格)。

我的协议看起来像这样:

@protocol MyCollectionViewDelegateLayout <UICollectionViewDelegate>
- (CGSize)sizeForCellAtIndexPath:(NSIndexPath *)indexPath;
- (CGSize)sizeForHeaderAtIndexPath:(NSIndexPath *)indexPath;
@end

我的集合视图控制器具有以下结构:

@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);
}

在我的prepareLayout子类中的UICollectionViewLayout方法内,我调用这些方法来预先计算必要的属性:

@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
    }
    ...
}
...

使用扩展数据源协议允许代码维护MVC Separation of Concerns。这里,布局类仍然不知道有关底层数据的任何信息,但能够使用它来定义属性。相反,控制器类不会放置任何内容,而只是根据基础数据提供大小调整提示。