使用estimatedSize

时间:2016-07-05 14:18:10

标签: ios uicollectionview uicollectionviewcell uicollectionviewlayout

我有一个奇怪的问题,当使用动态尺寸的集合视图时,使用固定尺寸时不会发生此问题。

重新加载后,每个部分的第一个单元格会消失,但前提是它们不在屏幕之外。经过几次测试后,我意识到细胞没有消失,但隐藏在剖面标题之下。

你知道造成这种情况的原因是什么吗?

没有重新加载的集合:

Collection without reloading

使用单元格可见重新加载后的集合:

Collection after reloading with cell visible

使用单元格重新加载屏幕后的集合:

Collection after reloading with cell out of screen

重新加载后单元格的3D视图:

3D view of the cell after reloading

代码:

#pragma mark - UICollectionViewDataSource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {

    return self.sections.count;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)sectionIndex {

    Section *section = [self.sections objectAtIndex:sectionIndex];
    return section.items.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    Section *section = [self.sections objectAtIndex:indexPath.section];
    Item *item = [section.items objectAtIndex:indexPath.row];

    if (self.editing) {
        EditingCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell-editing" forIndexPath:indexPath];
        cell.item = item;
        return cell;
    } else {
        BasicCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
        cell.item = item;
        return cell;
    }
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
        HeaderCollectionReusableView *header = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"header" forIndexPath:indexPath];
        Section *section = [self.sections objectAtIndex:indexPath.section];
        header.title = section.title;

        return header;
    } else {
        UICollectionReusableView *footer = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"footer" forIndexPath:indexPath];

        return footer;
    }
}
@implementation DetailCollectionViewLayout

- (instancetype)init {
    if (self = [super init]) {
        [self initialize];
    }

    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self initialize];
    }

    return self;
}

- (void)prepareLayout {
    CGFloat cellWidth = (isIPAD) ? 288 : CGRectGetWidth(self.collectionView.bounds);
    CGFloat headerWidth = CGRectGetWidth(self.collectionView.bounds);

    //    CGFloat ratio = (isIPAD) ? 0.33 : 0.66;
    self.estimatedItemSize = CGSizeMake(cellWidth, 53);
    self.headerReferenceSize = CGSizeMake(headerWidth, 50);
    self.footerReferenceSize = CGSizeMake(headerWidth, 1 + self.minimumInteritemSpacing);
    [super prepareLayout];
}

- (void)initialize {
    self.minimumLineSpacing = 0;
    self.minimumInteritemSpacing = (isIPAD) ? 5 : 10;
    self.estimatedItemSize = CGSizeZero;
    self.scrollDirection = UICollectionViewScrollDirectionVertical;
    self.sectionInset = UIEdgeInsetsZero;
}

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}

@end

我制作了一个简单的示例项目并录制视频:http://sendvid.com/330uo5jm

看起来问题是第一个单元格的位置。

3 个答案:

答案 0 :(得分:0)

.estimatedItemSize自动调整可能有点,呃......即使在最好的时候也很有趣。我过去曾遇到过这个问题,也有类似的问题。

CGRectZero使用不同的值,越接近实际的项目大小越好。我注意到你最初使用的是itemSize的大小。我不建议这样做。只需在开始时设置一次,其值接近您的尺寸。尝试一些值,看看哪些适合你。对我来说,需要进行一些微调。

对于为iOS 10开发的任何人(在撰写本文时尚未发布),都有一个新的集合视图属性,它允许集合视图确定估计的大小本身。将UICollectionViewFlowLayoutAutomaticSize设置为.estimatedItemSize,您无需明确设置SELECT FTSC.name AS CatalogName, T.name AS TableName, C.name AS ColumnName, FTSIU.user_scans, FTSIU.last_user_scan FROM sys.fulltext_catalogs AS FTSC JOIN sys.fulltext_indexes AS FTSI ON FTSC.fulltext_catalog_id = FTSI.fulltext_catalog_id JOIN sys.dm_db_index_usage_stats AS FTSIU ON FTSI.object_id = FTSIU.object_id AND FTSI.unique_index_id = FTSIU.index_id JOIN sys.tables AS T ON FTSI.object_id = T.object_id JOIN sys.columns AS C ON FTSI.object_id = C.object_id AND FTSI.unique_index_id = C.column_id WHERE FTSIU.database_id = DB_ID()

答案 1 :(得分:0)

确保您的代码中的 estimatedItemSize 与xib或storyboard中的单元格大小相同。不要更改它的大小运行时。

可以使用像......这样的标识符进行检查吗?

NSString *CellIdentifier = [NSString stringWithFormat:@"%d_%d",indexPath.section,indexPath.row];

答案 2 :(得分:0)

如果估计的大小与单元格的实际大小有很大差异,有时会发生这种情况。

  1. 检查您是否有明显的上下限制结果(如果您使用自动布局)。

  2. 是否存在可以破坏自动布局以正常工作的内容? E.g压缩阻力设置?

  3. 重新加载后,您确定该单元格有数据吗? (会很奇怪,但要确定,只需仔细检查一下。)

  4. 同样,Apple在这里表示Apple - self sizing guide尝试将尺寸估计设置为尽可能接近实际尺寸。

    您也可以尝试在使用自己的集合布局时引用集合布局的失效。请参阅Possible flow-layout help

    尽量将估算设置得尽可能接近,您将看到它是否能解决您的问题。