Reputation: 6477
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
}
And here is the output. It clearly scales with the image size.
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
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