2

I'm having a weird issue, when using a collection view with dynamic sizes, this issue doesn't happens while using fixed sizes.

After a reload the first cell of each section disappears, but only if they are out of the screen. After a few tests I realize that the cell didn't disappear, but its hidden bellow the section header.

Do you have any idea what is causing this?

Collection without reloading:

Collection without reloading

Collection after reloading with cell visible:

Collection after reloading with cell visible

Collection after reloading with cell out of screen:

Collection after reloading with cell out of screen

3D view of the cell after reloading:

3D view of the cell after reloading

The code:

#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

I made a simple sample project and record a video: http://sendvid.com/330uo5jm

It looks like the issue is the position from the first cell.

Emil Sierżęga
  • 1,785
  • 2
  • 31
  • 38
fnxpt
  • 434
  • 3
  • 13
  • Show us the collection view delegate and datasource code – Ahmad Ishfaq Jul 05 '16 at 14:21
  • Edited the original post, I only have a data source, the layout is defined by a custom UICollectionViewFlowLayout – fnxpt Jul 05 '16 at 14:36
  • Dynamic sizing depend on the constraints used in cell. It is possible that the header cell is ending up with a zero height due to incorrect constraints. A common problem is that the constraints are added to the cell view, when they should be added to the cell's contentView. You can try narrow this down by setting `clipToBounds = true` on the header cell. If the header disappears then the constraints are likely are fault. Please post your code for setting the constraints in the header view (or a screen grab of interface builder). – Luke Van In Jul 09 '16 at 21:58
  • @LukeVanIn if this was the case the second cell should appear after the first one, but it appears after the space where the first cell should be.... Another thing is that the first cell only disappears when reloading and if it's not visible – fnxpt Jul 09 '16 at 22:16
  • @fnpxt I understood that your screenshots are showing a header cell and the first cell. If this is the case, and the header is reporting a height of zero (or some other inconsistent height), then you will get the behaviour you're seeing. It is possible for the header to report a zero size, and still display at a different size outside of the measured bounds. Enabling clipping is just an easy test. There may be other causes, although it's quite common to find incorrect auto-layout as the cause when dynamic sizing isn't behaving as expected. – Luke Van In Jul 09 '16 at 23:29
  • @fnpxt Apart from that, another possible cause is not setting the scroll direction for the UICollectionView (which is used to determine the width of dynamic headers). Whatever the case, it's hard to tell without seeing the other parts of the system. – Luke Van In Jul 09 '16 at 23:30
  • Scroll direction and header size is defined in collection view layout as you can see in my first post.... I will try to put new screenshots tomorrow to display the remaining cells – fnxpt Jul 09 '16 at 23:59
  • @LukeVanIn updated the third screenshot... With this you can see that the first cell is hidden bellow the header and then you have a space where the cell should be and you have the second cell in the correct place – fnxpt Jul 11 '16 at 10:09

3 Answers3

0

UICollectionViewCell autosizing can be a little, uh... interesting even at the best of times. I've had this exact issue in the past, and similar issues too.

Use a different value for .estimatedItemSize, the closer to the actual item size the better. I noticed you're using a size of CGRectZero at first. I wouldn't recommend doing that. Just set it once, at the start, with a value close to your size. Try a few values, see what works for you. For me, it took a bit of fine tuning.

For anyone developing for iOS 10 (at the time of writing this hasn't been released) there is a new collection view property that lets the collection view determine the estimated size itself. Set the itemSize to UICollectionViewFlowLayoutAutomaticSize, you shouldn't need to set .estimatedItemSize explicitly.

Jordan Smith
  • 10,310
  • 7
  • 68
  • 114
0

make sure your estimatedItemSize in your code same as size of cell in your xib or storyboard.Don't changes it's size runtime.

can you check with use of identifier like...

NSString *CellIdentifier = [NSString stringWithFormat:@"%d_%d",indexPath.section,indexPath.row];
Bhoomi Jagani
  • 2,413
  • 18
  • 24
0

Sometimes it happens if you have a big difference between estimated size and real size of cell.

  1. Check you have a clear consequence of top to bottom constraints (if you are using autolayout).

  2. Is there something that can break the autolayout to work properly ? E.g compresion resistance settings ?

  3. Are you sure there are data for the cell after reload ? (Will be weird, but to be sure, just double check that.)

Also as Apple denotes here Apple - self sizing guide try to set the estimation of size as close as possible to real dimensions.

You can also try to refer to invalidation of collection layout as you are using your own. Refer to Possible flow-layout help

Try to set the estimation as close as possible and you will see if it solve your problem.

Community
  • 1
  • 1
Radim Halfar
  • 536
  • 2
  • 6
  • 15