0

I have a problem resizing the cells of a collection view to fit their content. I have a method that works fine, but with iOS 14 this method fails and no longer works. The code I am using is:

In the layout (subclass of UICollectionViewFlowLayout:

- (CGRect)frameForItemAtIndexPath:(NSIndexPath *)indexPath
                      withYOffset:(CGFloat)yOffset {
  CGFloat x = 0.0;
  CGFloat y = yOffset;
  CGFloat width = self.collectionView.bounds.size.width - self.collectionView.contentInset.left - self.collectionView.contentInset.right;
  CGFloat height = [self.delegate heightForItemAtIndexPath:indexPath];
  
  return CGRectMake(x, y, width, height);
}

In the view controller:

- (CGFloat)heightForItemAtIndexPath:(NSIndexPath *)indexPath {
    MyCollectionViewCell *cell = [self.dataSource sizingCellAtIndexPath:indexPath];
    [cell setFrame:CGRectMake(cell.bounds.origin.x, cell.bounds.origin.y, UIScreen.mainScreen.bounds.size.width, cell.bounds.size.height)];
    CGSize size = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize
                      withHorizontalFittingPriority:UILayoutPriorityRequired
                            verticalFittingPriority:UILayoutPriorityDefaultLow];
    return size.height;
}

As I said, this works fine until iOS 13.x but with iOS 14 fails and breaks the constraints. I have been searching a lot, and in stackoverflow there are a lot of answers but nothing seems to work for this.

Does someone know why this is not working on iOS 14 and how fix this?

Thanks in advance.

UPDATE

The method sizingCellAtIndexPath called in the first line of the method in the controller is:

- (MyCollectionViewCell *)sizingCellAtIndexPath:(NSIndexPath *)indexPath {
    Article *article = [self articleAtIndexPath:indexPath];
    NSString *cellIdentifier = [self cellIdentifierForCellAtIndexPath:indexPath];
    MyCollectionViewCell *sizingCell = [MyCollectionViewCell sizingCellWithNibName:cellIdentifier];
            
    [sizingCell configureWithArticle:article sizing:YES cellIdentifier:cellIdentifier indexPath:(NSIndexPath *)indexPath];
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];
            
    return sizingCell;
}
Asneroll
  • 155
  • 1
  • 3
  • 10
  • I suspect you set the size incorrectly. To set the width equal to the device width will create trouble as you need to adjust for section and content insets. Also, it seems you set the frame and return the height so it is not clear how you set it here. You would typically implement ```-collectionView:layout:sizeForItemAtIndexPath``` and if that is what you do give the surrounding code as well otherwise clarify your method a bit more. – skaak Nov 27 '20 at 07:58
  • The width is the same as the device width because the collection view has only a column (for other reasons it cannot be changed to a table view). And this was working well until iOS 14 arrived, so I suspect that there is a change with the new iOS but I haven't found what is – Asneroll Nov 27 '20 at 08:04
  • Ok - but why don't you just deque and reuse the cell and use that method I mention to set the size in the delegate. Also, even for a single column you still need to adjust for insets. – skaak Nov 27 '20 at 13:07
  • It's an inherited development and changing that is not an option at this moment. The point is that the method used has been working until iOS 13.x! Anyway, with `collectionView:layout:sizeForItemAtIndexPath` the size also has to be calculated – Asneroll Nov 27 '20 at 17:48
  • You have my sympathy! I just *think* that it will be easier if you can move the size functionality to that delegate method rather than try and fix the inherited code. In stead of calculating the height where you do, move the code over into that method and return the size. You can test that with minimal effort. – skaak Nov 27 '20 at 18:37
  • I will try the day I have a free moment. Thanks for your help :) – Asneroll Nov 27 '20 at 18:52

0 Answers0