Deepak Sharma
Deepak Sharma

Reputation: 6477

Disable dynamic sizing in UICollectionViewFlowLayout

I have a UICollectionViewFlowLayout assigned in UICollectionView. It's delegate method returns fixed CGSize in sizeForItemAtIndexPath. The problem is if UICollectionViewCell contains UIImageView or any other dynamically sized view with autolayout constraints that match leading, trailing, top, bottom to contentView, the cell resizes depending on the size of image in the imageView. Is it possible to get fixed size cells with UICollectionViewFlowLayout? I tried setting intrinsicContentSize for UIImageView in storyboard but it doesn't work.

Adding more details with code:

let numberOfItemsPerRow = 3
let spacingBetweenCells = CGFloat(40.0)
let sizeOfItem = CGFloat(210.0)

var sectionInsets:UIEdgeInsets {
    let margin:CGFloat = collectionView.bounds.width - CGFloat(numberOfItemsPerRow) * sizeOfItem - CGFloat(numberOfItemsPerRow - 1) * spacingBetweenCells
    return UIEdgeInsets(top: 30, left: margin/2, bottom: 30, right: margin/2)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
   
    NSLog("Cell size \(sizeOfItem)")
    return CGSize(width: sizeOfItem, height: sizeOfItem)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return sectionInsets
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return spacingBetweenCells
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mediaCell", for: indexPath) as! ThumbViewCell
    
    cell.mediaItem = mediaItems[indexPath.item]
    
    if let thumbURL = mediaItem.thumbURL, let image = UIImage(contentsOfFile: thumbURL.path) {
        cell.thumbnailView.image = image
        cell.thumbnailView.contentMode = .scaleAspectFill
    } 
     
    return cell
}

enter image description here

enter image description here

And here is the output. It clearly scales with the image size.

enter image description here

Here is console log:

 2022-06-04 11:47:34.599808+0400 SmrtImageCam[17794:1098605] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x155d0d9c0>, and it is attached to <UICollectionView: 0x156023400; frame = (262.5 0; 931.5 834); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x280438690>; layer = <CALayer: 0x280a7f560>; contentOffset: {0, -50}; contentSize: {931.5, 770}; adjustedContentInset: {50, 0, 20, 0}; layout: <UICollectionViewFlowLayout: 0x155d0d9c0>; dataSource: <SmrtImageCam.LibraryController: 0x1574082e0>>.


 Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
The behavior of the UICollectionViewFlowLayout is not defined because: the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
 Please check the values returned by the delegate.
 The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x155d0d9c0>, and it is attached to <UICollectionView: 0x156023400; frame = (262.5 0; 931.5 834); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x280438690>; layer = <CALayer: 0x280a7f560>; contentOffset: {0, -50}; contentSize: {931.5, 770}; adjustedContentInset: {50, 0, 20, 0}; layout: <UICollectionViewFlowLayout: 0x155d0d9c0>; dataSource: <SmrtImageCam.LibraryController: 0x1574082e0>>.
Make a symbolic breakpoint at  UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.

Upvotes: 0

Views: 757

Answers (1)

Deepak Sharma
Deepak Sharma

Reputation: 6477

I don't know if it's a known bug in iOS, but setting estimatedSize to .none for UICollectionViewFlowLayout in the Storyboard solves the problem as described in this answer in Apple Developer Forums.

Upvotes: 0

Related Questions