Large UICollectionViewCell disappear on scrolling

2019-08-30 11:37发布

问题:

I'm encountering the same problem as here which is that large UICollectionViewCell (more than twice of UICollectionView height apparently) disappear at a given scrolling offset and then reappear after a given scrolling offset also.

I've implemented @JonathanCichon solution which is to subclass UICollectionView and perform custom action on _visibleBounds (I know it's a private API but no matter, i don't need to submit it on Apple Store)

Here my custom collection view :

#import "CollectionView.h"

@interface UICollectionView ()

- (CGRect)_visibleBounds;

@end

@implementation CollectionView

- (CGRect)_visibleBounds
{
    CGRect rect = [super _visibleBounds];
    rect.size.height = [self heightOfLargestVisibleCell];
    return rect;
}

- (CGFloat)heightOfLargestVisibleCell
{
    // get current screen height depending on orientation
    CGFloat screenSize = [self currentScreenHeight];

    CGFloat largestCell = 0;

    NSArray *visibleCells = self.visibleCells;

    // get the largest height between visibleCells
    for (UITableViewCell *c in visibleCells)
    {
        CGFloat h = c.frame.size.height;
        largestCell = h > largestCell ? h : largestCell;
    }

    // return higher value between screen height and higher visible cell height
    return MAX(largestCell, screenSize);
}

This works, no more disappeared on scrolling but i still have a problem : if i perform reloadData when my scroll position is in the middle of a large cell, it disappear as earlier ... I've noticed that after reloading data, visibleCells return nil (in my heightOfLargestVisibleCell method), so it take my screen height for _visibleBounds but since screen height < to current visible cell height, this one is not displayed ...

Someone already faced this issue ?

Thx in advance

回答1:

I got a solution for your problem. I store the value calculated by heightOfLargestVisibleCell and return the last value after reload data.

@interface CollectionView : UICollectionView
@property (nonatomic, assign) CGFloat lastLargestCellHeight;
@property (nonatomic, assign) BOOL shouldEvalLargestCellHeight;

@end

@implementation CollectionView

- (CGRect)_visibleBounds
{
    CGRect rect = [super _visibleBounds];
    rect.size.height = [self heightOfLargestVisibleCell];
    return rect;
}


- (CGFloat)heightOfLargestVisibleCell
{
    if (self.shouldEvalLargestCellHeight) {
        // get current screen height depending on orientation
        CGFloat screenSize = self.frame.size.height;

        CGFloat largestCell = 0;

        NSArray *visibleCells = self.visibleCells;

        // get the largest height between visibleCells
        for (UITableViewCell *c in visibleCells)
        {
            CGFloat h = c.frame.size.height;
            largestCell = h > largestCell ? h : largestCell;
        }
        //return higher value between screen height and higher visible cell height
        self.lastLargestCellHeight = MAX(largestCell, screenSize);
        self.shouldEvalLargestCellHeight = NO;
    }
    return self.lastLargestCellHeight;
}

- (void)reloadData
{
    self.shouldEvalLargestCellHeight = NO;
    [super reloadData];
}

- (void)setContentOffset:(CGPoint)contentOffset
{
    self.shouldEvalLargestCellHeight = YES;
    [super setContentOffset:contentOffset];
}

@end